Как избежать использования setState в методе рендеринга? - PullRequest
0 голосов
/ 23 марта 2019

Я использую react-apollo для извлечения данных через <Query /> и <Mutation />.Таким образом, я хочу setState, когда я получаю некоторые данные.Я получаю данные в методе рендеринга.Вот так:

render() {
    return (
      <Query query={CAN_UPDATE_POST_QUERY} variables={{ id: this.props.router.query.postId }}>
        { payload => {

          if(payload.loading) {
            <div style={{width: '98%', textAlign: 'center', maxWidth: '1000px', margin: '50px auto'}}>Loading...</div>
          }

          if(this.isNew()){
            return (
              <PleaseSignIn>
                { me => (
                  ...something
                ) }
              </PleaseSignIn>
            )
          } else if (payload.data && payload.data.canUpdatePost) {

            // I get payload here. Here's where I want to set new state.
            this.canUpdatePost = payload.data.canUpdatePost
            this.setState({ canUpdatePost: this.canUpdatePost })


            return (
              <PleaseSignIn>
                { me => (
                  ...something
                ) }
              </PleaseSignIn>
            )


          } else {
            return (
              <div style={{width: '98%', textAlign: 'center', maxWidth: '1000px', margin: '50px auto'}}>You and your mind seems to be lost. ?</div>
            )
          }

        } }
      </Query>
    )
  }

Использование setState в рендере дает мне эту ошибку: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

Как мне мыслить в React?И особенно, как мне изменить свое состояние, когда я получаю полезную нагрузку от react-apollo?

NEWBIE HERE.Извините, если глупо.

Заранее спасибо.: -)

1 Ответ

0 голосов
/ 23 марта 2019

В общем, вы должны избегать использования setState в ваших функциях рендеринга.Вы должны избегать побочных эффектов (таких как состояние установки) в вашей функции рендеринга и вместо этого должны вызывать другие функции компонента для обработки изменений данных в вашем компоненте.

Функция render () должна быть чистой, то есть она не изменяет состояние компонента, возвращает каждый раз один и тот же результат и не взаимодействует напрямую с браузером.

См. Ссылку на метод render () в документации по реагированию: https://reactjs.org/docs/react-component.html#render

. Вы можете создать функцию вне метода визуализации для решения этой проблемы, например:

YourComponent extends React.Component {

   handleCanUpdatePost = (canUpdatePos) => {
     this.setState({ canUpdatePost })
   }

   render() {
       // Your render logic here
       // Whenever you want to setState do so by
       // calling this.handleCanUpdatePost(payload.data.canUpdatePost)
   }
}

Вам также, вероятно, следует проверить, не изменится ли значение состояния, прежде чем устанавливать его, чтобы избежать ненужных повторных визуализаций:

handleCanUpdatePost = (canUpdatePos) => {
     this.setState((state) => { 
       if(canUpdatePos !== state.canUpdatePost) {
         return {canUpdatePost: payload.data.canUpdatePost}
       } 
     })
   }
...