Я установил обратный вызов, который, в свою очередь, запускает реакцию цикла, и я не могу понять, почему?

#reactjs #callback

#reactjs #обратный вызов

Вопрос:

Я изучаю Reactjs, и теперь у меня что-то loop происходит, и я не могу понять, почему. Программа запускается, но ноутбук становится все теплее и теплее, и я устанавливаю точки останова и вижу, что код выполняется много раз..

У меня есть два Reactjs Components , и я создаю обратный onSetMasonryHeight() вызов и отправляю его в дочерний компонент.

Дочерний элемент отправляет обратно результат следующим образом:

  ---
    this.list = React.createRef();
    
    componentDidMount() {
    const { onSetMasonryHeight } = this.props;
     setTimeout(() => {
        onSetMasonryHeight(this.list.current.clientHeight);
     }, 50);
   }
  ---
  

Эту работу я получаю clientHeight , но она выполняется только один раз, поэтому componentDidMount()

Итак, я делаю то же самое в: componentDidUpdate() потому что после каждого render() мне нужно clientHeight

 ...
      componentDidUpdate() {
        const { onSetMasonryHeight } = this.props;
        setTimeout(() => {
            onSetMasonryHeight(this.list.current.clientHeight);
        }, 50);
      }
...
  

И в родительском Component я устанавливаю это clientHeight значение

 ---
    onSetMasonryHeight = val => {
        this.setState(() => {
            return { masonryHeight: val };
        });
    };
...
  

Теперь цикл запущен, но странно то, что приложение работает, и я вижу clientHeight , что значение является ожидаемым значением, но ноутбук становится все теплее и теплее, Боже мой, я должен вытащить вилку, лол.

Я выполняю отладку с помощью точки останова и вижу render() , что is запускается как для материнской, так и для дочерней системы в цикле, и похоже, что родительский метод onSetMasonryHeight = val => {.. , который имеет a return setState() render() , также запускает дочернюю систему, и это создает цикл.

Есть ide? Или как я могу сделать это лучше, может быть?

Ответ №1:

измените свой componentDidUpdate на это:

 componentDidUpdate(prevProps, prevState) {
  if (prevState.masonryHeight !== this.state.masonryHeight) {
  const { onSetMasonryHeight } = this.props;
    setTimeout(() => {
        onSetMasonryHeight(this.list.current.clientHeight);
    }, 50);
 }
}
  
  • вы должны проверить, произошло ли изменение состояния перед вызовом setState в противном случае вы получаете бесконечное обновление состояния, которое создает ад для вашего ноутбука