在 react-apollo 的 Query 组件中设置状态

Posted

技术标签:

【中文标题】在 react-apollo 的 Query 组件中设置状态【英文标题】:Setting state in the Query component of react-apollo 【发布时间】: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 的解决方案对我有用。 【参考方案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 提出的问题。您可能并不总是希望在 中呈现组件。其他地方的一些数据可能首先依赖于它的完成。

以上是关于在 react-apollo 的 Query 组件中设置状态的主要内容,如果未能解决你的问题,请参考以下文章

从 react-apollo 模拟 <Query />

React-Apollo - 查询 - renderProp:反应警告:无法对未安装的组件执行反应状态更新

如何在 react-apollo graphql 查询中正确使用动态变量?

React-Apollo,不要在组件加载时运行查询

无效的挂钩调用。钩子只能在使用 react-apollo 的函数组件内部调用

reactjs / jest:无法使用 MockedProvider 用数据填充 react-apollo 组件?