Apollo Client 2 + React:查询加载完成时的回调方法咨询
解决Apollo Client加载完成后填充邮箱字段的问题
嘿,我懂你的困扰——Apollo的异步查询在componentDidMount执行时还没完成,这时候确实拿不到邮箱值对吧?别担心,有几个实用的方法能搞定这个问题:
方法1:直接使用props中的数据(最推荐)
其实你完全不需要额外用setState存邮箱,Apollo会自动把查询结果同步到组件props里。等数据加载完成后,直接在render里把this.props.data.user.email绑定到input的value属性就好:
import React from 'react'; import gql from 'graphql-tag'; import { graphql } from 'react-apollo'; class AccountPage extends React.Component { render() { if (this.props.data.loading) return <p>Loading...</p>; // 直接从props中取邮箱值绑定到输入框 const userEmail = this.props.data.user.email; return( <form> <input type="email" value={userEmail} /> </form> ) } } const UserQuery = gql` query UserQuery { user { _id email } } `; export default graphql(UserQuery)(AccountPage);
这种方式最简洁,不需要维护组件自己的状态,后续如果用户邮箱有更新,Apollo也会自动同步到输入框里。
方法2:用componentDidUpdate更新组件状态
如果你确实需要把邮箱存在组件本地状态里(比如要做本地编辑后再提交),可以用componentDidUpdate监听props的变化,等数据加载完成后更新state:
import React from 'react'; import gql from 'graphql-tag'; import { graphql } from 'react-apollo'; class AccountPage extends React.Component { state = { email: '' }; componentDidUpdate(prevProps) { // 避免重复更新,只在数据加载完成且邮箱有变化时更新state if (this.props.data.user && this.props.data.user.email !== this.state.email) { this.setState({ email: this.props.data.user.email }); } } render() { if (this.props.data.loading) return <p>Loading...</p>; return( <form> <input type="email" value={this.state.email} /> </form> ) } } const UserQuery = gql` query UserQuery { user { _id email } } `; export default graphql(UserQuery)(AccountPage);
这里加了判断条件,能避免不必要的setState调用,防止组件无限重渲染。
方法3:使用Apollo查询的onCompleted回调
你还可以在高阶组件的配置里添加onCompleted回调,让查询完成时直接触发组件状态更新,示例如下:
import React from 'react'; import gql from 'graphql-tag'; import { graphql } from 'react-apollo'; class AccountPage extends React.Component { state = { email: '' }; handleQueryCompleted = (data) => { if (data.user) { this.setState({ email: data.user.email }); } }; render() { if (this.props.data.loading) return <p>Loading...</p>; return( <form> <input type="email" value={this.state.email} /> </form> ) } } const UserQuery = gql` query UserQuery { user { _id email } } `; export default graphql(UserQuery, { options: () => ({ onCompleted: (data) => this.handleQueryCompleted(data) }) })(AccountPage);
不过这种方法需要把回调函数关联到查询配置里,和方法2效果类似,但触发时机更直接。
总结一下,优先选方法1,简洁又省心;如果需要本地编辑邮箱,方法2是最适配的选择。
内容的提问来源于stack exchange,提问作者Evanss
相关产品推荐
相关产品推荐

