如何避免在 render 方法中使用 setState?

How to avoid using setState in render method?

我正在使用 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?

获取有效载荷时,如何改变我的状态

这里是新手。对不起,如果愚蠢。

提前致谢。 :-)

一般来说,您应该避免在渲染函数中使用 setState。您应该避免在渲染函数中产生副作用(例如设置状态),而应该调用其他组件函数来处理组件中的数据更改。

The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.

请参阅 React 文档中的 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}
       } 
     })
   }