使用旧方式:
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`将不再被调用。
答案 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
的组件周围。