在尝试更改模态内的值时收到上述警告:
我有一个弹出窗口,当我更改模式中国家代码字段的值时,一切都很好。但是,一旦我保存或关闭模态,状态变量的值就会变得不确定。
主要模式文件:
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>
)
}
和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>
)
}
我尝试记录newPhoneNumber
的值,并且按预期方式工作,只是当我更改值并关闭模式或尝试保存它时,它记录为未定义状态,并且出现白屏。
答案 0 :(得分:2)
您可能正在卸载执行某些ajax请求的组件,然后根据respone更新状态。在返回响应之前已经卸载了组件,但是该功能继续运行并尝试更新不再装载的组件的状态。
处理此问题的适当方法是将请求存储在某个数组中,该数组将通过重新渲染而保留(例如,在useRef中)。然后在卸载组件时,在useEffect清理功能中使用Abort Controller API。