我正在尝试从我的 React 前端向我的 NodeJS API 发送 PATCH 请求。我想要一种情况,如果您单击编辑按钮,初始名称价格会出现在输入中以进行必要的编辑。然后编辑完成后,就可以更新了。显示初始数据工作正常,但保存它不起作用。我收到错误:
“警告:无法对已卸载的组件执行 React 状态更新。这是一个无操作,但它表明应用程序中存在内存泄漏。要修复此问题,请取消 useEffect 清理函数中的所有订阅和异步任务。”
我已经查找了清理功能,但没有取得进展。 下面是我的代码:
const EditUserForm = () => {
const history = useHistory();
const match = useRouteMatch();
let routeId = match.params.id;
console.log(routeId);
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [item, setItem] = useState({});
const [name, setName] = useState();
const [price, setPrice] = useState();
const handleInputChange = (e) => {
console.log(e.target.value)
const { name, value } = e.target;
setItem({ ...item, [name]: value});
};
const handleSubmit = (e) => {
e.preventDefault();
updateProduct();
history.push('/');
}
const updateProduct = () => {
fetch(`/addproducts/${routeId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: item.name,
price: item.price
}),
})
.then((res) => res.json())
.then((result) => setItem(result))
.catch((err) => console.log('error: ', err))
}
useEffect(() => {
fetch(`/products/${routeId}`, requestOptions)
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setName(result.product.name);
setPrice(result.product.price);
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, []);
return (
<form onSubmit={handleSubmit} >
<label>Name</label>
<input
type="text"
name="name"
defaultValue={name}
onChange={handleInputChange}
/>
<label>Price</label>
<input
type="text"
name="price"
defaultValue={price}
onChange={handleInputChange}
/>
<button type="submit">Update</button>
<button>
Cancel
</button>
</form>
)
}
export default EditUserForm
在“handleSubmit”中,您正在调用“history.push('/')”,这会产生错误,如果您想更改路线,请在updateProduct的.then
中调用它你的useEffect函数适用于每一个渲染并且不可取消,尝试像这样重写它
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
fetch(`/products/${routeId}`, {signal, ...requestOptions})
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setName(result.product.name);
setPrice(result.product.price);
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
return controller.abort //so the fetch request can be canceled if the effect is re-executed
}, [routeId]); //only needs to rerun on route change
我不太确定句柄提交是否可能会导致类似的问题,在这种情况下,您需要执行与此类似的操作。