使用react-intl-tel-input时触发React未挂载组件状态更新警告如何解决
问题根因
- 警告触发来自两个叠加逻辑:
- 当前表单提交逻辑缺失原生行为拦截,触发整页跳转时Signup组件会被强制卸载,仍在等待响应的axios请求返回时,就会尝试在已销毁的组件上执行操作
- react-intl-tel-input组件内部的异步国家码匹配、手机号格式校验逻辑,未做组件卸载状态校验,在组件销毁流程中会触发一次残留的状态更新,和上面的逻辑叠加触发React的卸载后状态更新警告。
修复步骤
- 拦截原生表单默认提交行为
在handleSubmit方法第一行添加e.preventDefault(),杜绝原生表单跳转带来的组件强制销毁场景。 - 全组件维度增加挂载状态标记
引入useRef、useEffect维护组件的挂载状态,拦截所有卸载后的状态更新操作:import React, {useState, useRef, useEffect} from "react"; // ... function Signup() { // 初始化挂载状态标识 const isMounted = useRef(true); useEffect(() => { // 组件卸载时更新标识 return () => { isMounted.current = false; } }, []) - 给axios异步请求增加挂载状态判断
将请求的响应、错误处理逻辑全部包裹在状态判断分支中,避免组件卸载后执行任何组件内操作:const handleSubmit = async (e) => { e.preventDefault(); const signupData = { email, password, mobile}; try { const response = await axios.post("/url", signupData); if (isMounted.current) { // 原有响应处理逻辑 } } catch (err) { if (isMounted.current) { // 原有错误处理逻辑 } } } - 给IntlTelInput的状态回调增加挂载判断
拦截组件内部异步触发的手机号变更回调,避免组件销毁时执行残留的状态更新:<IntlTelInput containerClassName="intl-tel-input" inputClassName="form-control w-100" autoPlaceholder separateDialCode defaultCountry="za" name="mobile" numberType="MOBILE" fieldId="mobile_number" onPhoneNumberChange={(validate, value, countryData) => { if (isMounted.current) { setMobile(value) } }} formatOnInit={false} autoComplete="new-phone" /> - 组件配置兜底
可根据当前使用的react-intl-tel-input版本,补充loadUtils="async"配置,拆分国家码工具脚本的加载时机,避免脚本异步加载完成时组件已被销毁的场景,从组件侧减少残留回调的触发概率。
内容的提问来源于stack exchange,提问作者Anuja Shrivastava
相关产品推荐
相关产品推荐

