Apollo Client Mutation错误处理及组件更新方案咨询
处理GraphQL Mutation错误并更新组件的方案
嘿,我来帮你搞定这个错误处理的问题!你现在用的是react-apollo的graphql高阶组件,要在catch里更新组件状态的话,有几个实用的方案:
1. 通过ownProps传递组件内部的状态更新函数
如果你的Register组件本身已经维护了错误相关的状态(比如用来展示错误信息的errorMessage),可以把更新这个状态的方法通过props传递给高阶组件,然后在catch里调用它:
首先,你的Register组件大概是这样的:
class Register extends React.Component { state = { errorMessage: '' }; setErrorMessage = (message) => { this.setState({ errorMessage: message }); }; render() { // 渲染注册表单,同时展示错误信息 return ( <div> {this.state.errorMessage && <div className="error">{this.state.errorMessage}</div>} {/* 表单输入项等内容 */} </div> ); } }
然后在你的gqlWrapper里,通过ownProps拿到setErrorMessage并在catch里调用:
const gqlWrapper = graphql(registerMutation, { props: ({ mutate, ownProps }) => ({ registerUser: userDetails => { mutate({ variables: { ...userDetails }, update: (proxy, resp) => { // 基于成功结果更新本地状态 } }).catch(err => { console.log(err); // 提取服务器返回的GraphQL错误信息 const errorMsg = err.graphQLErrors?.[0]?.message || '注册失败,请重试'; // 调用组件的状态更新方法 ownProps.setErrorMessage(errorMsg); }); } }) });
2. 用withState给高阶组件添加错误状态
如果不想让Register组件自己管理错误状态,可以用recompose的withState工具,给高阶组件添加错误状态,再把状态和更新方法传给Register:
首先安装并引入recompose:
npm install recompose
然后修改你的代码:
import { compose, withState } from 'recompose'; const gqlWrapper = compose( withState('errorMessage', 'setErrorMessage', ''), graphql(registerMutation, { props: ({ mutate, ownProps }) => ({ registerUser: userDetails => { mutate({ variables: { ...userDetails }, update: (proxy, resp) => { // 成功时清空错误信息 ownProps.setErrorMessage(''); // 基于成功结果更新本地状态 } }).catch(err => { console.log(err); const errorMsg = err.graphQLErrors?.[0]?.message || '注册失败,请重试'; ownProps.setErrorMessage(errorMsg); }); }, // 把错误状态和更新方法传给Register组件 errorMessage: ownProps.errorMessage, setErrorMessage: ownProps.setErrorMessage }) }) ); export default gqlWrapper(Register);
这样Register组件就能直接通过this.props.errorMessage拿到错误信息,不用自己维护state了。
3. 使用Apollo的errorPolicy(推荐方案)
Apollo Client提供了errorPolicy配置,设置为'all'后,即使请求有错误,mutate也会进入then而不是catch,错误信息会包含在响应的errors字段里,这样更符合Apollo的数据流:
const gqlWrapper = graphql(registerMutation, { props: ({ mutate, ownProps }) => ({ registerUser: userDetails => { mutate({ variables: { ...userDetails }, update: (proxy, resp) => { // 基于成功结果更新本地状态 }, errorPolicy: 'all' // 关键配置 }).then(resp => { if (resp.errors) { // 处理错误 const errorMsg = resp.errors[0].message || '注册失败,请重试'; ownProps.setErrorMessage(errorMsg); } else { // 处理成功逻辑 ownProps.setErrorMessage(''); } }); } }) });
这种方式避免了使用catch,能更统一地处理成功和错误的情况,也能更好地和Apollo的缓存机制配合。
内容的提问来源于stack exchange,提问作者JamesG
相关产品推荐
相关产品推荐

