【问题标题】:How to avoid using setState in render method?如何避免在渲染方法中使用 setState?
【发布时间】:2019-08-14 02:57:42
【问题描述】:

我正在使用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 获取有效负载时,如何更改我的状态?

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

提前致谢。 :-)

【问题讨论】:

标签: javascript reactjs graphql react-apollo next.js


【解决方案1】:

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

render() 函数应该是纯函数,即不修改组件状态,每次调用都返回相同的结果,不直接与浏览器交互。

请参阅 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)
   }
}

您还应该在设置之前检查 state 的值是否会发生变化,以避免不必要的重新渲染:

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

【讨论】:

  • 今天不得不说,你是神❤️
  • 将 setState 调用从 render 方法移动到 render 方法调用的函数除了混淆 setState 调用之外没有任何作用。 render 方法仍在调用 setState,只是通过另一个函数。真正的解决方案是更改组件逻辑,使 setState 调用在其他生命周期方法中,如 componentDidMount 等
猜你喜欢
  • 2016-05-19
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 2019-10-17
  • 2022-01-25
  • 2020-12-21
  • 1970-01-01
  • 2017-12-30
相关资源
最近更新 更多