如何将react-apollo 2.1 Mutation组件与React生命周期方法结合使用?
嘿,这个场景我太熟悉了!用react-apollo的<Mutation>组件时,确实不像之前的HOC那样能直接把loading作为props拿到组件里用componentDidUpdate监听,但其实有几种很实用的办法能实现你要的效果,我给你一步步拆解:
1. 类组件方案:把loading状态提升到父组件
核心思路是将<Mutation>内部的loading同步到父组件的state中,这样就能在componentDidUpdate里对比前后状态变化,触发后续的通知mutation。
class YourPage extends React.Component { state = { mainMutationLoading: false, }; componentDidUpdate(prevProps, prevState) { // 监听loading从true变为false的瞬间 if (prevState.mainMutationLoading && !this.state.mainMutationLoading) { // 调用通知弹窗的mutation this.notifyMutation({ variables: { message: '操作已完成!' } }); } } render() { return ( <div> {/* 主操作的Mutation组件 */} <Mutation mutation={YOUR_MAIN_MUTATION}> {(mutate, { loading }) => { // 同步loading状态到父组件 if (loading !== this.state.mainMutationLoading) { this.setState({ mainMutationLoading: loading }); } return ( <button onClick={() => mutate({ variables: { /* 你的参数 */ } })} disabled={loading} > {loading ? '处理中...' : '执行操作'} </button> ); }} </Mutation> {/* 通知弹窗的Mutation组件 */} <Mutation mutation={NOTIFY_MUTATION}> {(notifyMutation) => { // 把mutate方法存到实例上,方便在componentDidUpdate调用 this.notifyMutation = notifyMutation; return null; // 不需要渲染UI,只拿方法 }} </Mutation> </div> ); } }
2. 函数组件方案:用Hooks监听状态变化
如果你的项目已经用了函数组件,用useState和useEffect就能轻松实现:
import { useState, useEffect, useRef } from 'react'; import { Mutation } from 'react-apollo'; function YourPage() { const [mainLoading, setMainLoading] = useState(false); // 用ref存通知mutation的方法,避免每次渲染更新依赖 const notifyMutationRef = useRef(null); useEffect(() => { // 当loading从true变为false时触发通知 if (!mainLoading && notifyMutationRef.current) { notifyMutationRef.current({ variables: { message: '操作已完成!' } }); } }, [mainLoading]); return ( <div> <Mutation mutation={YOUR_MAIN_MUTATION}> {(mutate, { loading }) => { setMainLoading(loading); return ( <button onClick={() => mutate({ variables: { /* 你的参数 */ } })} disabled={loading} > {loading ? '处理中...' : '执行操作'} </button> ); }} </Mutation> <Mutation mutation={NOTIFY_MUTATION}> {(notifyMutation) => { notifyMutationRef.current = notifyMutation; return null; }} </Mutation> </div> ); }
3. 简化方案:直接用Mutation的回调(适合关注结果的场景)
如果你的需求是只有当mutation成功/失败时才触发通知,可以直接用<Mutation>自带的onCompleted和onError回调,不用监听loading:
<Mutation mutation={YOUR_MAIN_MUTATION} onCompleted={() => { notifyMutation({ variables: { message: '操作成功!' } }); }} onError={() => { notifyMutation({ variables: { message: '操作失败,请重试!' } }); }} > {(mutate, { loading }) => ( <button onClick={() => mutate({ variables: { /* 你的参数 */ } })} disabled={loading} > {loading ? '处理中...' : '执行操作'} </button> )} </Mutation>
总结
本质上,<Mutation>组件是通过children函数传递内部状态的,所以只要把loading状态“提出来”到父组件的状态管理中,就能复用你之前用componentDidUpdate的思路——不管是类组件还是函数组件,核心都是监听loading状态的变化时机,再触发后续操作。
内容的提问来源于stack exchange,提问作者Vic
相关产品推荐
相关产品推荐

