Должен ли я использовать условные обновления setState в componentDidUpdate в React 16?

#javascript #reactjs #setstate

#javascript #reactjs #setstate

Вопрос:

Я использую React 16, и мне нужно вызвать условное setState внутри componentDidUpdate. setState выполняется асинхронно. Итак, обычно, если мне нужно использовать state для вычисления моего следующего состояния, я должен использовать функцию updater в качестве аргумента setState. В React 16 добавлена возможность отменить обновление setState, вернув значение null из setState. Итак, должен ли я использовать функцию обновления для создания условного setState?

Код с программой обновления:

 componentDidUpdate(prevProps, prevState) {
    const prevValue = prevProps.value;
    this.setState((state, props) => {
        const nextValue = props.value;
        if (prevValue === nextValue) return null;
        const isIncreasing = prevValue < nextValue;
        if (prevState.isIncreasing === isIncreasing) return null;
        return { isIncreasing };
    });
}
  

Код без средства обновления:

 componentDidUpdate(prevProps, prevState) {
    const prevValue = prevProps.value;
    const nextValue = this.props.value;
    if (prevValue === nextValue) return;
    const isIncreasing = prevValue < nextValue;
    if (prevState.isIncreasing === isIncreasing) return;
    this.setState({ isIncreasing });
}
  

Ответ №1:

Я думаю, что нет никакой разницы, кроме стилистической. Лично я предпочитаю второй подход. В любом случае вы вызовете другой цикл рендеринга, поэтому в качестве альтернативы вы можете использовать getDerivedStateFromProps which будет выполняться до рендеринга компонента и не требует условий для предотвращения бесконечных циклов:

 static getDerivedStateFromProps(props, state) {
  return {
    prevValue: props.value,
    isIncreasing: props.value > state.prevValue, // First time will always be true since state.prevValue is undefined FYI
  };
}
  

Комментарии:

1. спасибо, getDerivedState может помочь мне избежать второго рендеринга! Я был в замешательстве, как получить prevProps в нем. Итак, отличная идея!