如何解决React 历史导致错误:“警告:无法对卸载的组件执行 React 状态更新......”
我在 React 中有这段代码:
import React,{ useRef,useEffect,useState } from 'react';
import { Link } from 'react-router-dom';
import { useForm } from "react-hook-form";
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
import { userService,alertService } from '@/_services';
function AddEdit({ history,match }) {
const { id } = match.params;
const isAddMode = !id;
const cancelButton = useRef(null);
// form validation rules
const validationSchema = Yup.object().shape({
title: Yup.string()
.required('Title is required'),fullname: Yup.string()
.required('Full Name is required'),age: Yup.string()
.required('Age Name is required'),email: Yup.string()
.email('Email is invalid')
.required('Email is required'),role: Yup.string()
.required('Role is required'),password: Yup.string()
.transform(x => x === '' ? undefined : x)
.concat(isAddMode ? Yup.string().required('Password is required') : null)
.min(1,'Password must be at least 1 characters'),confirmPassword: Yup.string()
.transform(x => x === '' ? undefined : x)
.when('password',(password,schema) => {
if (password || isAddMode) return schema.required('Confirm Password is required');
})
.oneOf([Yup.ref('password')],'Passwords must match')
});
// functions to build form returned by useForm() hook
const { register,handleSubmit,reset,setValue,errors,formState } = useForm({
resolver: yupResolver(validationSchema)
});
function onSubmit(data) {
return isAddMode
? createUser(data)
: updateUser(id,data);
}
function createUser(data) {
return userService.create(data)
.then(() => {
alertService.success('User added',{ keepAfterRouteChange: true });
history.push('.');
})
.catch(alertService.error);
}
function updateUser(id,data) {
return userService.update(id,data)
.then(() => {
alertService.success('User updated',{ keepAfterRouteChange: true });
history.push('..');
})
.catch(alertService.error);
}
const [user,setUser] = useState({});
const [showPassword,setShowPassword] = useState(false);
useEffect(() => {
let isSubscribed = true
if (!isAddMode) {
// get user and set form fields
userService.getById(id).then(user => {
if (isSubscribed) {
const fields = ['title','fullname','age','email','role'];
fields.forEach(field => setValue(field,user[field]));
setUser(user);
}
});
}
return () => isSubscribed = false
},[]);
return (
<form onSubmit={handleSubmit(onSubmit)} onReset={reset}>
<h1>{isAddMode ? 'Add User' : 'Edit User'}</h1>
<div className="form-row">
<div className="form-group col">
<label>Title</label>
<select name="title" ref={register} className={`form-control ${errors.title ? 'is-invalid' : ''}`}>
<option value=""></option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
</select>
<div className="invalid-feedback">{errors.title?.message}</div>
</div>
<div className="form-group col-5">
<label>First Name</label>
<input name="fullname" type="text" ref={register} className={`form-control ${errors.fullname ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.fullname?.message}</div>
</div>
<div className="form-group col-5">
<label>Last Name</label>
<input name="age" type="text" ref={register} className={`form-control ${errors.age ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.age?.message}</div>
</div>
</div>
<div className="form-row">
<div className="form-group col-7">
<label>Email</label>
<input name="email" type="text" ref={register} className={`form-control ${errors.email ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.email?.message}</div>
</div>
<div className="form-group col">
<label>Role</label>
<select name="role" ref={register} className={`form-control ${errors.role ? 'is-invalid' : ''}`}>
<option value=""></option>
<option value="User">User</option>
<option value="Admin">Admin</option>
</select>
<div className="invalid-feedback">{errors.role?.message}</div>
</div>
</div>
{!isAddMode &&
<div>
<h3 className="pt-3">Change Password</h3>
<p>Leave blank to keep the same password</p>
</div>
}
<div className="form-row">
<div className="form-group col">
<label>
Password
{!isAddMode &&
(!showPassword
? <span> - <a onClick={() => setShowPassword(!showPassword)} className="text-primary">Show</a></span>
: <em> - {user.password}</em>
)
}
</label>
<input name="password" type="password" ref={register} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.password?.message}</div>
</div>
<div className="form-group col">
<label>Confirm Password</label>
<input name="confirmPassword" type="password" ref={register} className={`form-control ${errors.confirmPassword ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.confirmPassword?.message}</div>
</div>
</div>
<div className="form-group">
<button type="submit" disabled={formState.isSubmitting} className="btn btn-primary">
{formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"<!-- end snippet -->></span>}
Save
</button>
<Link to={isAddMode ? '.' : '..'} className="btn btn-link" ref={cancelButton}>Cancel</Link>
</div>
</form>
);
}
export { AddEdit };
但是当“createUser”或“updateUser”函数被调用并执行“history.push('.')警告:无法在未安装的组件上执行React状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。;"应用程序返回带有记录列表的屏幕并生成控制台警报消息:“警告:无法对已卸载的组件执行 React 状态更新。这是一个空操作,但它表示内存泄漏在您的应用程序中。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。"。
有人知道如何解决这个问题吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。