在 Apollo 查询组件 returns 结果后调度 redux 操作
Dispatch redux action after Apollo Query component returns result
使用旧方法:
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>
);
}
这将导致以下警告:
Cannot update during an existing state transition (such as within render
or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount
.
问题是使用 <Query>,
componentWillMount` 将不再被调用。
新的 Query
组件使用 render props 模式。作为组件的子组件传入的函数在 Query
的 render 方法中被调用,这意味着您无权访问该组件的任何其他生命周期方法在函数里面。为了解决这个问题,您必须创建一个额外的组件来实现您需要的生命周期方法。只有一种方法可以做到这一点:
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
.
的组件周围
使用旧方法:
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>
);
}
这将导致以下警告:
Cannot update during an existing state transition (such as within
render
or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved tocomponentWillMount
.
问题是使用 <Query>,
componentWillMount` 将不再被调用。
新的 Query
组件使用 render props 模式。作为组件的子组件传入的函数在 Query
的 render 方法中被调用,这意味着您无权访问该组件的任何其他生命周期方法在函数里面。为了解决这个问题,您必须创建一个额外的组件来实现您需要的生命周期方法。只有一种方法可以做到这一点:
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
.