【问题标题】:Setting state in the Query component of react-apollo在 react-apollo 的 Query 组件中设置状态
【发布时间】:2018-10-30 09:56:23
【问题描述】:

所以,我正在尝试为从服务器获取数据的编辑组件设置初始状态,现在应该可以在组件状态下进行编辑。但是当我尝试这样做时:

<Query query={POST_QUERY} variables={{ id: this.props.match.params.id }}>
    {({ data, loading, error }) => {
      this.setState({ title: data.title })

我陷入了无限循环,因为这是在渲染中。我不应该将组件状态与查询组件一起使用吗?如果没有,还有什么选择?

【问题讨论】:

  • Query组件内的任何具体的setState,可以直接传给子组件
  • @PiyushBhati,在我的例子中,我正在使用一个需要由状态控制的输入的实时表单验证器。
  • @rma 在渲染函数中使用 setState 不是一个好主意。您可以在容器内使用查询组件并将值传递给另一个组件,使用该组件的gDSFP 将其设置为状态,然后您可以使用您的验证器。
  • 完全同意,@PiyushBhati,谢谢。目前,上述 DanielRearden 的解决方案对我有用。

标签: reactjs react-apollo


【解决方案1】:

任何需要这些数据作为状态的组件都应该在Query 组件中呈现,然后将数据作为道具传递给它。例如:

class MyComponent extends React.Component {
  constructor (props) {
    this.state = {
      title: props.post.title
    }
  }
}

<Query query={POST_QUERY} variables={{ id: this.props.match.params.id }}>
  {({ data, loading, error }) => {
    <MyComponent post={data.post}/>
  }}
</Query>

【讨论】:

  • 您必须确保仅在 data.post 存在且未加载时渲染 MyComponent。除非,大多数时候你会得到“未定义”的值。
  • @daniel-rearden 您好,我已经尝试过您的解决方案,但它在类组件中不起作用。您如何在类外定义 QUERY 组件。
  • 我不明白这是如何回答这个问题的。获取数据后在哪里设置状态?
【解决方案2】:

您可以使用Querycomponent 上的onCompleted 属性来设置状态。见下例:

class MyComponent extends React.Component {
  constructor (props) {
    this.state = {
      isFirstRender: true
      title: props.post.title
    }
  }
  
  setTitle = title => {
    if (this.state.isFirstRender){
        this.setState({title, isFirstRender: false})
    }
  }
  
  render () {
    return <Query
             query={POST_QUERY}
             variables={{ id: this.props.match.params.id }} 
             onCompleted={data => this.setTitle(data.post.title)}
           >
      {({ data, loading, error }) => {
        <MyComponent post={data.post}/>
      }}
    </Query>
  }
}

编辑:

由于onCompleted多次触发的bug已经在react-apollo的最新版本中得到解决,我们现在可以简单地做:

  ...
     <Query
        query={POST_QUERY}
        variables={{ id: this.props.match.params.id }}
        onCompleted={data => this.setState({ title: data.post.title})}
     >
      {({ data, loading, error }) => {
         <MyComponent post={data.post}/>
      }}
    </Query>
  )
  ...

【讨论】:

  • 一旦你设置了状态,组件将重新渲染,apollo 将再次获取数据,因此无限循环。
  • @RemigiusKalimbaJr 不,实际上在重新渲染时if (this.state.isFirstRender) 将是错误的,因此循环会中断
  • 但它还会触发 Query 两次吗?
  • @SutikshanDubey 这似乎是react-apollo 中的一个错误github.com/apollographql/react-apollo/issues/2522 有一个持续的问题
  • 这应该是公认的答案,因为它充分回答了 OP 提出的问题。您可能并不总是希望在 中呈现组件。其他地方的一些数据可能首先依赖于它的完成。
猜你喜欢
  • 2018-09-19
  • 2019-02-17
  • 2019-02-11
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2018-10-29
  • 2016-09-27
相关资源
最近更新 更多