![](/img/trans.png)
[英]Unable to get the updated state when using React useState hook
[英]Why react state (useState) is updated but not updated when log it?
您好,我正在嘗試創建一個簡單的多文件組件,但文件狀態未按預期運行。
FileUpload 組件工作正常,當用戶選擇一個文件並開始上傳時, onStart
prop 方法被調用。 然后當它成功完成時,'onFinish' prop 方法被調用。 這段代碼似乎很好,可以在onfinish
方法中安慰對象。 它在被onStart Method
修改之前控制對象的舊值。 我希望控制台中的文件對象值包含緩沖區鍵,因為它是在onStart
方法時添加的,但它不存在。
示例初始狀態文件應為[]
當對狀態文件調用使用效果時應將狀態文件更新為[{_id:"example_unique_id"}]
然后將出現一個上傳按鈕,當用戶選擇一個文件和onStart
修改對象和狀態應該更新為[{_id:"example_unique_id", buffer:{}]
最后當它完成files
應該是[{_id:"example_unique_id", buffer:{}]
但這里它返回[{_id:"example_unique_id"}]
。
我會錯過什么?
另外,我安裝了 React Dev 工具,並且似乎在開發工具中狀態更新得很好。
import React, { useState } from 'react'
import { useEffect } from 'react';
import unique_id from 'uniqid'
import FileUpload from "./../../components/FileUpload";
const InlineFileUpload = ({ onFilesChange }) => {
const [files, setFiles] = useState([]);
function onFinish(file, id) {
const old_object = files.filter((file) => file._id == id)[0];
console.log("old object on after upload", old_object);
}
const addFile = (file, id) => {
const old_object = files.filter((file) => file._id == id)[0];
const index = files.indexOf(old_object);
const new_files = [...files];
new_files.splice(index, 1, { ...old_object, buffer: file });
setFiles(new_files);
};
useEffect(() => {
const new_attachments = files.filter(({ buffer }) => buffer == undefined);
if (new_attachments.length == 0) {
setFiles([...files, { _id: unique_id() }]);
}
const links = files.filter((file) => file.file !== undefined);
if (links.length !== 0) {
onFilesChange(links);
}
}, [files]);
return (
<>
{files.map((file) => {
const { _id } = file;
return ( <FileUpload
key={_id}
id={_id}
onStart={(e) => addFile(e, _id)}
onFinish={(e) => onFinish(e, _id)}
/>
);
})}
</>
);
};
export default InlineFileUpload
我認為問題是由於您的此代碼未更新狀態造成的:
const addFile = (file, id) => {
const old_object = files.filter((file) => file._id == id)[0];
const index = files.indexOf(old_object);
const new_files = [...files];
new_files.splice(index, 1, { ...old_object, buffer: file });
setFiles(new_files);
}
files
看起來像一個對象數組。 展開運算符不會對這個數組進行深拷貝。 網上有很多例子,這里舉一個。
let newArr = [{a : 1, b : 2}, {x : 1, y : 2}, {p: 1, q: 2}]; let arr = [...newArr]; arr[0]['a'] = 22; console.log(arr); console.log(newArr);
所以你的 new_files 是同一個數組。 Splice
必須進行一些修改,但已經到位。 所以當你在做這個setFiles(new_files);
,您基本上設置了與 newState 相同的對象引用。 React 不會檢測到更改,也不會更新任何內容。
您可以選擇為您的特定代碼實現深度復制方法或使用 lodash cloneDeep 。 查看您的代碼,這可能對您const new_files = JSON.parse(JSON.stringify(files))
: const new_files = JSON.parse(JSON.stringify(files))
。 它有點慢,您可能會丟失具有函數或符號等值的屬性。 讀
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.