React HO C с WrappedComponent в версии Hook Всегда повторно инициализируйте состояние - PullRequest
1 голос
/ 06 мая 2020

У меня есть HO C, в настоящее время я хочу обновить его до версии Hook, однако я обнаружил, что он всегда отображает

, давайте посмотрим пример:

const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
   const HOC = ({...props}) => {
       const [selected, setSelected] = useState(f());
       return <WrappedComponent {...props} setSelected={setSelected}/>
   }
   return HOC;
}

f () всегда будет вызываться, если триггер setSelected из WrappedComponent

посмотрим на другой пример:

const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
   class HOC extends Component {
         constructor(props) {
            super(props);
            this.state = {selected: f()}
            this.setSelected = this.setSelected.bind(this);
         }
         setSelected(value) {
            this.setState({selected:value})
        }
        render() {
           return <WrappedComponent {...props} setSelected={this.setSelected}/>

        }
  }

  return HOC;
}

f () будет вызывать только один раз

Как решить этот случай, если я должен использовать формат Ho c, но просто хочу, чтобы c сам стал функциональным компонентом?

или я просто меняю

const [selected, setSelected] = useState(f()); 

на

const [selected, setSelected] = useState(() => f());

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Вы неправильно используете useState.

Каждый раз при рендеринге HO C будет вызываться f().

Позвольте мне подробно рассказать, возможно, следующий код заставит вас увидеть более четко

const hoc = ({someProp = ""}) => WrappedComponent => {
   const HOC = ({...props}) => {
       const state = f(); // Sure, this line would be executed every time.
       const [selected, setSelected] = useState(state);
       ...
   }
  ...
}

Я предполагаю, что вы хотите выполнить f(), чтобы получить состояние инициализации при инициализации компонента, а затем позволить компоненту обрабатывать само состояние, хотя это не рекомендуемые.

Для этого сценария я бы предпочел один из следующих подходов:

  1. Передать результат f() от родителя к HO C компонент

    Это самый простой способ создать HO C и одновременно сгенерировать состояние инициализации

  2. используйте useEffect при первом рендеринге с пустым состоянием в порядке.

    Вы можете думать useEffect как старый didMount API жизненного цикла.

0 голосов
/ 06 мая 2020

ответ - изменение

const [selected, setSelected] = useState (f ());

на

const [selected, setSelected] = useState (( ) => f ());

и f () будут вызывать только один раз, независимо от того, сколько раз он рендерится, за исключением размонтирования

...