Làm thế nào để đẩy phần tử vào trong mảng useState React hook? Đó có phải là một phương pháp cũ trong trạng thái phản ứng? Hay một cái gì đó mới?
Ví dụ: ví dụ về setState push ?
Làm thế nào để đẩy phần tử vào trong mảng useState React hook? Đó có phải là một phương pháp cũ trong trạng thái phản ứng? Hay một cái gì đó mới?
Ví dụ: ví dụ về setState push ?
Câu trả lời:
Khi sử dụng useState
, bạn có thể nhận được phương thức cập nhật cho mục trạng thái:
const [theArray, setTheArray] = useState(initialArray);
sau đó, khi bạn muốn thêm một phần tử mới, bạn sử dụng hàm đó và truyền vào mảng mới hoặc một hàm sẽ tạo mảng mới. Thông thường là cái sau, vì các bản cập nhật trạng thái là không đồng bộ và đôi khi theo đợt:
setTheArray(oldArray => [...oldArray, newElement]);
Đôi khi bạn có thể thoát mà không cần sử dụng biểu mẫu gọi lại đó, nếu bạn chỉ cập nhật mảng trong trình xử lý cho một số sự kiện người dùng cụ thể như click
(nhưng không giống như mousemove
):
setTheArray([...theArray, newElement]);
Các sự kiện mà React đảm bảo rằng kết xuất được tuôn ra là "các sự kiện rời rạc" được liệt kê ở đây .
Ví dụ trực tiếp (chuyển một cuộc gọi lại vào setTheArray
):
Bởi vì bản cập nhật duy nhất theArray
trong đó là bản trong một click
sự kiện (một trong những sự kiện "rời rạc"), tôi có thể nhận được bản cập nhật trực tiếp trong addEntry
:
useEffect
ví dụ đó ...?
useEffect
có một danh sách phụ thuộc trống []
, nó sẽ chỉ được thực thi trong lần hiển thị đầu tiên. Vì vậy, giá trị của theArray
bên trong hiệu ứng sẽ luôn là initialArray
. Trong các tình huống setTheArray([...initialArray, newElement])
không có ý nghĩa và khi theArray
hằng số luôn bằng initialValue
, thì cần cập nhật chức năng.
Để mở rộng thêm một chút, đây là một số ví dụ phổ biến. Bắt đầu với:
const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);
Đẩy phần tử vào cuối mảng
setTheArray(prevArray => [...prevArray, newValue])
Đẩy / cập nhật phần tử ở cuối đối tượng
setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));
Đẩy / cập nhật phần tử ở cuối mảng đối tượng
setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);
Đẩy phần tử vào cuối đối tượng của mảng
let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);
Đây cũng là một số ví dụ làm việc. https://codesandbox.io/s/reacthooks-push-r991u
Tương tự như cách bạn làm với trạng thái "bình thường" trong các thành phần lớp React.
thí dụ:
function App() {
const [state, setState] = useState([]);
return (
<div>
<p>You clicked {state.join(" and ")}</p>
//destructuring
<button onClick={() => setState([...state, "again"])}>Click me</button>
//old way
<button onClick={() => setState(state.concat("again"))}>Click me</button>
</div>
);
}
// Save search term state to React Hooks with spread operator and wrapper function
// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))
// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))
// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])
// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])
https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc
setTheArray([...theArray, newElement]);
là câu trả lời đơn giản nhất nhưng hãy cẩn thận đối với sự đột biến của các mục trong Array . Sử dụng nhân bản sâu các mục mảng.
Phương pháp được đề xuất nhiều nhất là sử dụng hàm wrapper và toán tử spread cùng nhau. Ví dụ: nếu bạn đã khởi tạo một trạng thái có tên name
như thế này,
const [names, setNames] = useState([])
Bạn có thể đẩy sang mảng này như thế này,
setNames(names => [...names, newName])
Hy vọng rằng sẽ giúp.
Tôi đã thử các phương pháp trên để đẩy một đối tượng vào một mảng đối tượng trong useState nhưng đã gặp lỗi sau khi sử dụng TypeScript :
Nhập 'TxBacklog [] | undefined 'phải có một phương thức' Symbol.iterator 'trả về một iterator.ts (2488)
Thiết lập cho tsconfig.json rõ ràng là đúng:
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es6",
],
Cách giải quyết này đã giải quyết được vấn đề (mã mẫu của tôi):
Giao diện:
interface TxBacklog {
status: string,
txHash: string,
}
Biến số đưa ra:
const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();
Đẩy đối tượng mới vào mảng:
// Define new object to be added
const newTx = {
txHash: '0x368eb7269eb88ba86..',
status: 'pending'
};
// Push new object into array
(txBacklog)
? setTxBacklog(prevState => [ ...prevState!, newTx ])
: setTxBacklog([newTx]);
nếu bạn muốn đẩy sau chỉ mục cụ thể, bạn có thể làm như sau:
const handleAddAfterIndex = index => {
setTheArray(oldItems => {
const copyItems = [...oldItems];
const finalItems = [];
for (let i = 0; i < copyItems.length; i += 1) {
if (i === index) {
finalItems.push(copyItems[i]);
finalItems.push(newItem);
} else {
finalItems.push(copyItems[i]);
}
}
return finalItems;
});
};
setTheArray(currentArray => [...currentArray, newElement])
nếu cách trên không hoạt động. Nhiều khả năng tronguseEffect(...theArray..., [])
, điều quan trọng là nhận ra rằngtheArray
là một hằng số, vì vậy thông tin cập nhật chức năng là cần thiết cho các giá trị từ tương lai ám