简体   繁体   English

警告:更新上下文并重定向到另一个页面后,无法在未安装的组件上执行 React state 更新

[英]Warning: Can't perform a React state update on an unmounted component after update context and redirect to another page

I am having a problem which needs your helps我有一个需要你帮助的问题

I have a changeProfile function which will be executed after onClick in /editpage我有一个changeProfile function 将在/editpage onClick的 onClick 之后执行

const appContext = useContext(AppContext);
const [userLogin, setUserLogin] = appContext.userLogin;
const [userProfile, setUserProfile] = useState<UserProfile>({
    name: userLogin.name,
    ....
});
const changeProfile = e => {
    e.preventDefault();
    post(API)
        .then(() => {
            setUserLogin({
                ...userLogin,
                name: userProfile.name,
            });
            router.push('/mypage');
        })
        .catch(error => {
            setEditError(error[0]);
            window.scrollTo(0, 0);
        });
};

context.tsx上下文.tsx

const [userLogin, setUserLogin] = useState({
     email: '',
     name: '',
     ....
});

after page redirects to /mypage , console logs warning error as title and it only logs warning at the first time (if I back to /editpage and changeProfile one more time, console logs nothing in /mypage )页面重定向到/mypage后,控制台将警告错误记录为标题,并且仅在第一次记录警告(如果我再次返回/editpagechangeProfile ,控制台将在/mypage中不记录任何内容)

I have tried to redirect after setUserLogin done as code below but it's not working我尝试在setUserLogin完成后redirect ,但它不起作用

const changeProfile = e => {
    e.preventDefault();
    post(API)
        .then(() => {
            setUserLogin({
                ...userLogin,
                name: userProfile.name,
            });
        })
        .catch(error => {
            setEditError(error[0]);
            window.scrollTo(0, 0);
        });
};

const firstUpdate = useRef(true);
useLayoutEffect(() => {
    if (firstUpdate.current) {
        firstUpdate.current = false;

        return;
    }
    console.log(userLogin); //already updated
    router.push('/mypage');
}, [userLogin]);

Thanks for reading!谢谢阅读!

PS: Problem can be solved with PS:问题可以解决

setTimeout(() => {
    router.push('/mypage');
}, 1000);

but its absolutely not a right choice但它绝对不是一个正确的选择

As the warning suggests, because your API code is asynchronous, if you redirect away from the page too fast, the setState may occur after the component has already been unmounted.正如警告所暗示的,由于您的 API 代码是异步的,因此如果您重定向离开页面的速度过快,则可能会在组件已卸载后发生 setState。 What you can do, is use the callback argument of setState (assuming you're calling setState somewhere in the setUserLogin function), to redirect after the state update has already been completed.您可以做的是使用setStatecallback参数(假设您在setUserLogin函数的某处调用setState ),在 state 更新完成重定向。

Edit : You could try adding another state variable to your context to signify that an update has been performed, something like updated: false and then with your setUserLogin call:编辑:您可以尝试将另一个 state 变量添加到您的上下文中,以表示已执行更新,例如updated: false ,然后使用您的setUserLogin调用:

setUserLogin({
    ...userLogin,
    name: userProfile.name,
    updated: true
});

Then you can use the useEffect hook to check for this condition and then redirect:然后你可以使用useEffect钩子来检查这种情况,然后重定向:

useEffect(() => {
    if (userLogin.updated) {
        router.push('/mypage');
    }
})

Then at some point, you would have to reset this variable to false .然后在某个时候,您必须将此变量重置为false However, now that I know your setUserLogin is coming from the AppContext component, I think the issue is that this component is getting unmounted when it shouldn't be.但是,既然我知道您的setUserLogin来自AppContext组件,我认为问题是该组件在不应该被卸载时被卸载。 Make sure you're rendering this component high enough in the component tree so that the mypage you redirect to still has this AppContext mounted确保你在组件树中渲染这个组件足够高,以便你重定向到的mypage仍然安装了这个AppContext

Edit 2 : A good approach to prevent this error is by adding a guard to a component class, which keeps track of whether the component is mounted or not.编辑 2 :防止此错误的一个好方法是向组件 class 添加防护,以跟踪组件是否已安装。 Something like this:像这样的东西:

class AppContext extends Component {
    _mounted = False;

    componentDidMount() {
        this._mounted = true;
    }

    componentWillUnmount() {
        this._mounted = false;
    }

    ...
}

Then, when you call setState or the update function from useState , you can first check to see if the component is mounted or not before trying to update:然后,当您从useState调用setState或更新 function 时,您可以先检查组件是否已安装,然后再尝试更新:

if (AppContext._mounted) {
    setUserLogin({
        ...userLogin,
        name: userProfile.name,
        updated: true
    });
}

However, in your case, this may prevent the information from being updated as you expect, since the component is unmounting, which is why I think the issue lies with why the component is unmounting但是,在您的情况下,这可能会阻止信息按您的预期更新,因为组件正在卸载,这就是为什么我认为问题在于组件卸载的原因

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法对卸载的组件警告执行React状态更新 - Can't perform a React state update on an unmounted component warning 警告:无法对未安装的组件执行 React state 更新 - Warning: Can't perform a React state update on an unmounted component 无法摆脱:警告:无法对未安装的组件执行 React 状态更新 - Can't get rid of: Warning: Can't perform a React state update on an unmounted component 警告:无法对未安装的组件 React Native 执行 React 状态更新 - Warning: Can't perform a React state update on an unmounted component React Native React 警告:无法对卸载的组件执行 React 状态更新。 要修复,请取消所有订阅 - React Warning: Can't perform a React state update on an unmounted component. To fix, cancel all subscriptions React Native - 警告:无法对卸载的组件执行 React 状态更新 - React Native - Warning: Can't perform a React state update on an unmounted component 为什么我收到以下 React Native 警告:Can&#39;t perform a React state update on an unmounted component - Why am I getting the following React Native warning: Can't perform a React state update on an unmounted component React-Native:警告:无法对卸载的组件执行 React 状态更新 - React-Native: Warning: Can't perform a React state update on an unmounted component React:ComponentDidMount 中的 SetInterval 导致错误“警告:无法在未安装的组件上执行 React 状态更新。” - React: SetInterval in ComponentDidMount causing error "Warning: Can't perform a React state update on an unmounted component." 反应原生:警告:无法在未安装的组件上执行 React state 更新 - react native: Warning: Can't perform a React state update on an unmounted component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM