Apollo Query组件返回结果后调度redux操作

时间:2018-04-10 09:43:39

标签: reactjs redux apollo react-apollo

使用旧方式:

graphql(GET_PROJECTS_BY_USER_ID, {
    options: ownProps => ({
        skip: !ownProps.loggedUser.id,
    }),
    props: ({ data }) => {
        return data;
    },
});

我可以在componentWillReceiveProps生命周期内捕获项目列表并在那里发送redux操作:

componentWillReceiveProps(nextProps) {
    if (!nextProps.loading && this.props.loading) {
        this.props.setProjects(nextProps.getProjects);
    }
}

现在我正在尝试Apollo的<Query/>组件,但我无法弄清楚如何正确发送行动:

render() {
    return (
        <Query
            query={GET_PROJECTS_BY_USER_ID}
            skip={!this.props.loggedUserId}
        >
            {({ loading, data: { getProjects: projects } }) => {
                if (loading) return 'Loading ...';

                this.props.setProjects(projects); // no good

                // return projects
            }}
        </Query>
    );
}

这将导致以下警告:

  

无法在现有状态转换期间更新(例如在render或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数副作用是反模式,但可以移动到componentWillMount

问题是使用<Query>, componentWillMount`将不再被调用。

1 个答案:

答案 0 :(得分:2)

新的Query组件使用render props模式。在Query的渲染方法中调用作为组件子项传入的函数,这意味着您无法访问任何其他生命周期方法函数内部的那个组件。要解决这个问题,您必须创建一个实现所需生命周期方法的附加组件。只需一种方法:

class DoSomethingOnce extends Component {
  componentWillMount () {
    this.props.action()
  }
  render () {
    return this.props.children || null
  }
}

<Query
  query={GET_PROJECTS_BY_USER_ID}
  skip={!this.props.loggedUserId}
>
  {({ loading, data: { getProjects: projects } }) => {
    if (loading) return 'Loading ...';
    <DoSomethingOnce action={() => setProjects(projects)}>
      // whatever else you're going to render
    </DoSomethingOnce>
  }}
</Query>

或者,使用componentDidMount的组件可以执行所有渲染,而不是将降压传递给其子项。您也可以随时使用reactions/component等库。

这与您使用graphql HOC时没有什么不同 - 您仍然必须将该HOC包裹在实现componentDidMount的组件周围。