Javascript 反应警告:Can';t在未安装的组件上执行React状态更新。若要修复,请取消所有订阅

Javascript 反应警告:Can';t在未安装的组件上执行React状态更新。若要修复,请取消所有订阅,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,尝试更改模式内的值时,收到上述警告: 我有一个弹出窗口,当我更改模式中国家代码字段的值时,一切都很好。但是,一旦我保存或关闭模式,状态变量的值就会变得未定义 主模式文件: const EditDetailsModal = props => { const dispatch = useDispatch() const intl = useIntl() const shouldShowModal = useSelector(selectors.shouldShowEdi

尝试更改模式内的值时,收到上述警告:

我有一个弹出窗口,当我更改模式中国家代码字段的值时,一切都很好。但是,一旦我保存或关闭模式,状态变量的值就会变得未定义

主模式文件:

const EditDetailsModal = props => {
    const dispatch = useDispatch()
    const intl = useIntl()
    const shouldShowModal = useSelector(selectors.shouldShowEditDetailsModal)
  const name = useSelector(selectors.getName)
  const email = useSelector(selectors.getEmail)
    const phoneNumber = useSelector(selectors.getPhone)
    const country = useSelector(selectors.getCountry)
  const phoneCode = useSelector(selectors.getPhoneCountryCode)
    const [newName, setNewName] = React.useState(name)
    const [newEmail, setNewEmail] = React.useState(email)
    const [newPhone, setNewPhone] = React.useState(phoneNumber)
  const [newPhoneCode, setNewPhoneCode] = React.useState(phoneCode)
    
    const _handleOnModalHide = React.useCallback(() => {
    setNewEmail(email)
    setNewName(name)
    setNewPhone(phoneNumber)
    setNewCountry(country)
    setRequestPhoneValue(phoneNumber)
        dispatch(actions.hideEditDetailsModal())
    }, [dispatch, name, setNewName, email, newEmail, setNewEmail, phoneNumber, setNewPhone, country, setNewCountry, setRequestPhoneValue ])

  const _phoneCountryCodeChangeCallback = React.useCallback((code) => {
    setNewPhoneCode(code)
  },[setNewPhoneCode])

    const _handleSaveBtnClick = React.useCallback(() => {
        if (isSaveBtnActive) {
            dispatch(actions.startRequestEditPersonalDetails())
            setError('')
            editPersonalDetails({
                name: newName,
                email: newEmail,
                phone: requestPhoneValue,
                country: requestCountryValue,
                oldEmail: email,
        phone_code: newPhoneCode,
            }).then(response => {
                if (response && response.data && response.data.data) {
                    dispatch(actions.successEditPersonalDetails())
                    dispatch(actions.savePersonalDetails(response.data.data))
                    _handleOnModalHide()
                } else {
                    dispatch(actions.errorEditPersonalDetails())
                    if (response.data.errors[0] && response.data.http_message) {
                        setError(response.data.errors[0])
                    } else {
                        setError(intl.formatMessage({
                            id: "error.commonServerError"
                        }))
                    }
                }
            }).catch(error => {
                dispatch(actions.errorEditPersonalDetails())
                setError(intl.formatMessage({
                    id: "error.commonServerError"
                }))
            })
        }
    }, [newName, newEmail, requestPhoneValue, requestCountryValue, isSaveBtnActive])

    // handle response change
    React.useEffect(() => {
        setNewName(name)
    }, [name, setNewName, shouldShowModal])

    React.useEffect(() => {
        setNewEmail(email)
    }, [email, setNewEmail, shouldShowModal])

    React.useEffect(() => {
        setNewPhone(phoneNumber)
        setRequestPhoneValue(phoneNumber)
    }, [phoneNumber, setNewPhone, setRequestPhoneValue, shouldShowModal])

    React.useEffect(() => {
        setNewCountry(getCountryFromCode(country))
        setRequestCountryValue(country)
    }, [country, setNewCountry, setRequestCountryValue, shouldShowModal])

  React.useEffect(() => {
    setNewPhoneCode(phoneCode)
  }, [phoneCode, setNewPhoneCode, shouldShowModal])

    return (
        <div onClick={e => e.stopPropagation()}>
            <Modal 
                show={shouldShowModal} 
                onHide={_handleOnModalHide}
                className="editModal"
                backdropClassName="edit-details-modal-backdrop-custom"
                centered>
                <FormContainer>
                    <BlockUi tag="div" blocking={isRequestLoading}>
                        <Modal.Header className="editModalHeader" closeButton>
                            <Modal.Title>
                                <FormattedMessage id="modal.editPersonalDetails.title"/>
                            </Modal.Title>
                        </Modal.Header>
                        <Modal.Body>
                            <Form>
                                <Form.Group controlId="formBasicPhoneNumber">
                                    <ModalPhoneInput 
                                        initialValue={newPhone}
                                        changeCallback={_phoneChangeCallback}
                    countryChangeCallback={_phoneCountryCodeChangeCallback}
                    defaultCountryCode={newPhoneCode}/>
                                </Form.Group>

                                <SaveDetailsBtn 
                                    disabled={!isSaveBtnActive}
                                    onClick={_handleSaveBtnClick}>
                                    <FormattedMessage id="modal.editPersonalDetails.save"/>
                                </SaveDetailsBtn>
                            </Form>
                        </Modal.Body>
                    </BlockUi>
                </FormContainer>
            </Modal>
        </div>
    )
}
const editdailsmodal=props=>{
const dispatch=usedpatch()
常量intl=useIntl()
const shouldshowmodel=useSelector(selectors.shouldshoweditDetailsModel)
const name=useSelector(selectors.getName)
const email=useSelector(selectors.getEmail)
const phoneNumber=useSelector(selectors.getPhone)
const country=useSelector(selectors.getCountry)
const phoneCode=useSelector(selectors.getPhoneCountryCode)
const[newName,setNewName]=React.useState(name)
const[newEmail,setNewEmail]=React.useState(电子邮件)
const[newPhone,setNewPhone]=React.useState(电话号码)
const[newPhoneCode,setNewPhoneCode]=React.useState(phoneCode)
const_handleOnModalHide=React.useCallback(()=>{
setNewEmail(电子邮件)
setNewName(名称)
设置新电话(电话号码)
setNewCountry(国家)
setRequestPhoneValue(电话号码)
分派(actions.hideEditDetailsModel())
},[dispatch,name,setNewName,email,newEmail,setNewEmail,phoneNumber,setNewPhone,country,setNewCountry,setRequestPhoneValue])
const\u phoneCountryCodeChangeCallback=React.useCallback((代码)=>{
setNewPhoneCode(代码)
},[setNewPhoneCode])
const_handleSaveBtnClick=React.useCallback(()=>{
如果(isSaveBtnActive){
分派(actions.startRequestEditPersonalDetails())
设置错误(“”)
编辑个人资料({
姓名:newName,
电子邮件:newEmail,
phone:requestPhoneValue,
country:requestCountryValue,
旧电子邮件:电子邮件,
电话号码:新电话号码,
})。然后(响应=>{
if(response&&response.data&&response.data.data){
分派(actions.successEditPersonalDetails())
调度(actions.savePersonalDetails(response.data.data))
_handleOnModalHide()
}否则{
分派(actions.errorEditPersonalDetails())
if(response.data.errors[0]&&response.data.http\u消息){
setError(response.data.errors[0])
}否则{
setError(intl.formatMessage({
id:“error.commonServerError”
}))
}
}
}).catch(错误=>{
分派(actions.errorEditPersonalDetails())
setError(intl.formatMessage({
id:“error.commonServerError”
}))
})
}
},[newName,newEmail,requestPhoneValue,requestCountryValue,isSaveBtnActive])
//处理响应更改
React.useffect(()=>{
setNewName(名称)
},[name,setNewName,shouldShowModal])
React.useffect(()=>{
setNewEmail(电子邮件)
},[email,setNewEmail,shouldShowModal])
React.useffect(()=>{
设置新电话(电话号码)
setRequestPhoneValue(电话号码)
},[phoneNumber,setNewPhone,setRequestPhoneValue,shouldShowModal])
React.useffect(()=>{
setNewCountry(getCountryFromCode(国家))
setRequestCountryValue(国家/地区)
},[country,setNewCountry,setRequestCountryValue,shouldShowModal])
React.useffect(()=>{
setNewPhoneCode(电话码)
},[phoneCode,setNewPhoneCode,shouldShowModal])
返回(
e、 stopPropagation()}>
)
}
以及PhoneNumberInput文件:

const PhoneNumberInput = ({ initialValue, customPlaceholder, changeCallback,countryChangeCallback, defaultCountryCode, ...props }) =>  {

    const [countryCode, setCountryCode] = React.useState(defaultCountryCode.toUpperCase())

    const _handleOnCountryCodeChange = React.useCallback((code) => {
        countryChangeCallback(code)
    },[countryChangeCallback])

    React.useEffect(() => {
        if(defaultCountryCode) {
            const countryCodeUpper = defaultCountryCode.toUpperCase()
            setCountryCode(countryCodeUpper)
        }
    },[defaultCountryCode])

    return (
        <PhoneInputWrapper>
            <StyledPhoneInput
                value={value}
                onChange={_handleOnChange} 
                defaultCountry={countryCode}
                onCountryChange={_handleOnCountryCodeChange}  />
        </PhoneInputWrapper>
    )
}
constPhoneNumberInput=({initialValue,customPlaceholder,changeCallback,countryChangeCallback,defaultCountryCode,…props})=>{
const[countryCode,setCountryCode]=React.useState(defaultCountryCode.toUpperCase())
const\u handleOnCountryCodeChange=React.useCallback((代码)=>{
countryChangeCallback(代码)
},[countryChangeCallback])
React.useffect(()=>{
如果(默认国家代码){
const countryCodeUpper=defaultCountryCode.toUpperCase()
设置CountryCode(countryCodeUpper)
}
},[defaultCountryCode])
返回(
)
}
我尝试记录
newPhoneNumber
的值,它的工作与预期一样,只是当我更改值并关闭模式或尝试保存时,它记录未定义的值,并显示一个白色屏幕


您可能正在卸载一个组件,该组件执行一些ajax请求,然后根据响应更新状态。组件在返回响应之前已卸载,但函数继续并尝试更新不再装载的组件的状态

处理这种情况的方法是将请求存储在某个数组中,该数组将通过rerender持久化(例如在useRef中)。然后在组件卸载时,在useEffect清理函数中使用中止控制器API


本文可能会帮助您:

您可能正在卸载一个组件,该组件执行一些ajax请求,然后根据响应进行更新