如何使用graphQL在React/Apollo中setState()

IT技术 reactjs graphql graphql-js react-apollo
2021-05-12 14:03:37

我正在尝试将 setState() 设置为我从 graphQL 获得的查询结果,但我很难找到如何执行此操作,因为它将始终加载,或者仅从 props 中使用。我先设置状态

constructor (props) {
        super(props);
        this.state = { data: [] };

然后我有这个查询

const AllParams = gql`
    query AllParamsQuery {
        params {
            id,
            param,
            input
        }
    }`

当它回来时,我可以访问它 this.props.AllParamsQuery.params

如果 this.setState({ data: this.props.AllParamsQuery.params }) 没有它, 我应该如何以及何时返回{data: undefined}

我还没有找到一种方法让它等待,而它又是undefinedAKA loading: truethen setState我试过componentDidMount()componentWillReceiveProps()包括一个async function(){...await...}但没有成功,我可能做错了。有谁知道如何正确地做到这一点或有一个例子?

编辑 + 答案:您不应该设置状态而将其留在props中。查看此链接:“为什么在 react.js 中将props设置为状态是亵渎” http://johnnyji.me/react/2015/06/26/why-setting-props-as-state-in-react-is- blasphemy.html 更新props的问题还有很多,但在这个应用程序创建教程中可以找到一些很好的例子:https : //www.howtographql.com/react-apollo/8-subscriptions/

3个回答

一个简单的解决方案是将 Apollo 查询组件和 React 有状态组件分开。来自 Redux,使用mapStateToProps将传入的 props 转换为本地组件状态并不少见componentWillReceiveProps然而,这种模式在 Apollo 的<Query />.

因此,只需创建一个单独的组件来获取数据:

...

export class WidgetsContainer extends Component {
  render (
    <Query query={GET_WIDGETS}>
      {({ loading, error, data }) => {
        if (loading) return <Loader active inline="centered" />;

        const { widgets } = data;
        return (
          <Widgets widgets={widgets} />
        )
      }}
    </Query>
  )
}

现在Widgets组件现在可以setState正常使用了:

...
export class Widgets extends Component {
  ...
  constructor(props) {
    super()

    const { widgets } = props;
    this.state = {
      filteredWidgets: widgets
    };
  }

  filterWidget = e => {
    // some filtering logic
    this.setState({ filteredWidgets });
  }

  render() {
    const { filteredWidgets } = this.state;
    return (
      <div>
        <input type="text" onChange={this.filterWidgets} />
        {filteredWidgets.count}
      </div>
    )
  }
}

将其设置为 state 的原因是什么?请记住,Apollo Client 使用内部 redux 存储来管理查询。如果您尝试根据查询中的某些更改触发重新渲染,则应该使用 refetchQueries()。如果您绝对需要将它存储在本地状态,我认为您可能可以比较 componentWillReceiveProps 中的 nextProps 以检测加载(从 apollo 客户端执行查询时返回的值)何时发生更改,然后更新您的状态。

我有一个类似的问题(尽管它发生的原因完全不同)。我的状态一直设置为未定义。我能够用 React 中间件解决它。它使避免这个问题变得容易。我最终使用了超级代理。

http://www.sohamkamani.com/blog/2016/06/05/redux-apis/