Thay đổi giá trị trong mảng đối tượng javascript
Mảng có thể thay đổi trong JavaScript, nhưng bạn nên coi chúng là bất biến khi bạn lưu trữ chúng ở trạng thái. Cũng giống như với các đối tượng, khi bạn muốn cập nhật một mảng được lưu trữ trong trạng thái, bạn cần tạo một mảng mới (hoặc tạo một bản sao của mảng hiện có), sau đó thiết lập trạng thái để sử dụng mảng mới Show
Bạn sẽ học
Cập nhật mảng mà không có đột biếnTrong JavaScript, mảng chỉ là một loại đối tượng khác. Giống như với các đối tượng, bạn nên coi các mảng ở trạng thái React là chỉ đọc. Điều này có nghĩa là bạn không nên gán lại các mục bên trong một mảng như 8 và bạn cũng không nên sử dụng các phương thức làm thay đổi mảng, chẳng hạn như 9 và import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }0 Thay vào đó, mỗi khi bạn muốn cập nhật một mảng, bạn sẽ muốn chuyển một mảng mới vào hàm cài đặt trạng thái của mình. Để làm điều đó, bạn có thể tạo một mảng mới từ mảng ban đầu ở trạng thái của mình bằng cách gọi các phương thức không thay đổi của nó như import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }1 và import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }2. Sau đó, bạn có thể đặt trạng thái của mình thành mảng mới kết quả Đây là một bảng tham chiếu của hoạt động mảng phổ biến. Khi xử lý các mảng bên trong trạng thái React, bạn sẽ cần tránh các phương thức ở cột bên trái và thay vào đó hãy ưu tiên các phương thức ở cột bên phải tránh (biến đổi mảng)thích (trả về một mảng mới)thêm_______2_______3,import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }4_______2_______5, import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }6 cú pháp lây lan ()loại bỏ import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }7, import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }8, import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }9 0, 1 ()thay thếimport { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }9, 3 bài tập 4 ()sắp xếp_______12_______5, 6 trước tiên ()Ngoài ra, bạn có thể cho phép bạn sử dụng các phương thức từ cả hai cột cạm bẫyThật không may, 1 và import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }9 được đặt tên giống nhau nhưng lại rất khác nhau
Trong React, bạn sẽ sử dụng 1 (không có import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }2. ) thường xuyên hơn vì bạn không muốn thay đổi đối tượng hoặc mảng trong trạng thái. Cập nhật đối tượng giải thích đột biến là gì và tại sao nó không được khuyến nghị cho trạng thái Thêm vào một mảng 9 sẽ biến đổi một mảng mà bạn không muốnỨng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); artists.push({ id: nextId++, name: name, }); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }Cho xem nhiều hơn Thay vào đó, hãy tạo một mảng mới chứa các mục hiện có và một mục mới ở cuối. Có nhiều cách để làm điều này, nhưng cách dễ nhất là sử dụng cú pháp import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }4
Bây giờ nó hoạt động chính xác Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }Cho xem nhiều hơn Cú pháp dàn trải mảng cũng cho phép bạn thêm vào trước một mục bằng cách đặt nó trước bản gốc import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }5
Theo cách này, spread có thể thực hiện công việc của cả 9 bằng cách thêm vào cuối mảng và import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }7 bằng cách thêm vào đầu mảng. Hãy thử nó trong hộp cát ở trên Loại bỏ khỏi một mảngCách dễ nhất để xóa một mục khỏi mảng là lọc nó ra. Nói cách khác, bạn sẽ tạo ra một mảng mới không chứa mục đó. Để làm điều này, hãy sử dụng phương pháp 0, ví dụỨng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }Cho xem nhiều hơn Nhấp vào nút "Xóa" một vài lần và xem trình xử lý nhấp chuột của nó
Ở đây, import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }9 có nghĩa là “tạo một mảng bao gồm những 0 có ID khác với 1”. Nói cách khác, nút “Xóa” của mỗi nghệ sĩ sẽ lọc nghệ sĩ đó ra khỏi mảng, sau đó yêu cầu kết xuất lại với mảng kết quả. Lưu ý rằng 0 không sửa đổi mảng ban đầuChuyển đổi một mảngNếu bạn muốn thay đổi một số hoặc tất cả các phần tử của mảng, bạn có thể sử dụng import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }2 để tạo một mảng mới. Hàm mà bạn sẽ chuyển đến 4 có thể quyết định phải làm gì với từng mục, dựa trên dữ liệu hoặc chỉ mục của mục đó (hoặc cả hai)Trong ví dụ này, một mảng chứa tọa độ của hai hình tròn và hình vuông. Khi bạn nhấn nút, nó chỉ di chuyển các vòng tròn xuống 50 pixel. Nó thực hiện điều này bằng cách tạo ra một mảng dữ liệu mới bằng cách sử dụng import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }2 Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }Cho xem nhiều hơn Thay thế các mục trong một mảngViệc muốn thay thế một hoặc nhiều phần tử trong một mảng là điều đặc biệt phổ biến. Các phép gán như 8 đang thay đổi mảng ban đầu, vì vậy, thay vào đó, bạn cũng sẽ muốn sử dụng 4 cho việc nàyĐể thay thế một mục, hãy tạo một mảng mới với 4. Trong cuộc gọi 4 của bạn, bạn sẽ nhận được chỉ mục mục làm đối số thứ hai. Sử dụng nó để quyết định trả lại mục ban đầu (đối số đầu tiên) hay cái gì khácỨng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }Cho xem nhiều hơn Chèn vào một mảngĐôi khi, bạn có thể muốn chèn một mục vào một vị trí cụ thể không phải ở đầu cũng không phải ở cuối. Để làm điều này, bạn có thể sử dụng cú pháp trải rộng mảng import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }4 cùng với phương thức import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }1. Phương thức import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }1 cho phép bạn cắt một “lát cắt” của mảng. Để chèn một mục, bạn sẽ tạo một mảng trải rộng lát cắt trước điểm chèn, sau đó là mục mới và sau đó là phần còn lại của mảng ban đầu Trong ví dụ này, nút Chèn luôn chèn tại chỉ mục import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }3 Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }Cho xem nhiều hơn Thực hiện các thay đổi khác đối với một mảngCó một số điều bạn không thể làm với cú pháp trải rộng và các phương pháp không biến đổi như chỉ riêng import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }2 và import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }1. Ví dụ: bạn có thể muốn đảo ngược hoặc sắp xếp một mảng. Các phương thức import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }6 và import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }7 của JavaScript đang thay đổi mảng ban đầu, vì vậy bạn không thể sử dụng chúng trực tiếp Tuy nhiên, bạn có thể sao chép mảng trước rồi thực hiện các thay đổi đối với mảng đó Ví dụ Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba import { useState } from 'react'; let nextId = 3; const initialList = [ { id: 0, title: 'Big Bellies' }, { id: 1, title: 'Lunar Landscape' }, { id: 2, title: 'Terracotta Army' }, ]; export default function List() { const [list, setList] = useState(initialList); function handleClick() { const nextList = [...list]; nextList.reverse(); setList(nextList); } return ( <> <button onClick={handleClick}> Reverse button> <ul> {list.map(artwork => ( <li key={artwork.id}>{artwork.title}li> ))} ul> > ); }Cho xem nhiều hơn Ở đây, bạn sử dụng cú pháp trải rộng import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }8 để tạo một bản sao của mảng ban đầu trước. Bây giờ bạn đã có một bản sao, bạn có thể sử dụng các phương pháp biến đổi như import { useState } from 'react'; let initialShapes = [ { id: 0, type: 'circle', x: 50, y: 100 }, { id: 1, type: 'square', x: 150, y: 100 }, { id: 2, type: 'circle', x: 250, y: 100 }, ]; export default function ShapeEditor() { const [shapes, setShapes] = useState( initialShapes ); function handleClick() { const nextShapes = shapes.map(shape => { if (shape.type === 'square') { // No change return shape; } else { // Return a new circle 50px below return { ...shape, y: shape.y + 50, }; } }); // Re-render with the new array setShapes(nextShapes); } return ( <> <button onClick={handleClick}> Move circles down! button> {shapes.map(shape => ( <div key={shape.id} style={{ background: 'purple', position: 'absolute', left: shape.x, top: shape.y, borderRadius: shape.type === 'circle' ? '50%' : '', width: 20, height: 20, }} /> ))} > ); }9 hoặc import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }0 hoặc thậm chí chỉ định các mục riêng lẻ với import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }1 Tuy nhiên, ngay cả khi bạn sao chép một mảng, bạn không thể trực tiếp thay đổi các mục hiện có bên trong mảng đó. Điều này là do quá trình sao chép còn nông—mảng mới sẽ chứa các mục giống như mảng ban đầu. Vì vậy, nếu bạn sửa đổi một đối tượng bên trong mảng đã sao chép, bạn đang thay đổi trạng thái hiện có. Ví dụ, mã như thế này là một vấn đề 0Mặc dù import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }2 và import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }3 là hai mảng khác nhau, nhưng import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }4 và import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }5 trỏ đến cùng một đối tượng. Vì vậy, bằng cách thay đổi import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }6, bạn cũng đang thay đổi import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }7. Đây là một đột biến trạng thái, mà bạn nên tránh. Bạn có thể giải quyết vấn đề này theo cách tương tự —bằng cách sao chép các mục riêng lẻ mà bạn muốn thay đổi thay vì thay đổi chúng. Đây là cách Cập nhật các đối tượng bên trong mảngCác đối tượng không thực sự nằm trong các mảng bên trong. Chúng có thể xuất hiện "bên trong" trong mã, nhưng mỗi đối tượng trong một mảng là một giá trị riêng biệt, mà mảng "chỉ" tới. Đây là lý do tại sao bạn cần cẩn thận khi thay đổi các trường lồng nhau như import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }5. Danh sách tác phẩm nghệ thuật của người khác có thể trỏ đến cùng một phần tử của mảng Khi cập nhật trạng thái lồng nhau, bạn cần tạo các bản sao từ điểm bạn muốn cập nhật và cho đến cấp cao nhất. Hãy xem cách nó hoạt động Trong ví dụ này, hai danh sách tác phẩm nghệ thuật riêng biệt có cùng trạng thái ban đầu. Chúng được cho là bị cô lập, nhưng do đột biến, trạng thái của chúng vô tình bị chia sẻ và việc chọn một hộp trong một danh sách sẽ ảnh hưởng đến danh sách kia Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba 1Cho xem nhiều hơnVấn đề là trong mã như thế này 2Mặc dù bản thân mảng import { useState } from 'react'; let initialCounters = [ 0, 0, 0 ]; export default function CounterList() { const [counters, setCounters] = useState( initialCounters ); function handleIncrementClick(index) { const nextCounters = counters.map((c, i) => { if (i === index) { // Increment the clicked counter return c + 1; } else { // The rest haven't changed return c; } }); setCounters(nextCounters); } return ( <ul> {counters.map((counter, i) => ( <li key={i}> {counter} <button onClick={() => { handleIncrementClick(i); }}>+1button> li> ))} ul> ); }9 là mới, nhưng bản thân các phần tử vẫn giống như trong mảng import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }0 ban đầu. Vì vậy, việc thay đổi import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }1 sẽ thay đổi mục tác phẩm nghệ thuật gốc. Tác phẩm nghệ thuật đó cũng nằm trong import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }2, gây ra lỗi. Những lỗi như thế này có thể khó nghĩ đến, nhưng may mắn là chúng sẽ biến mất nếu bạn tránh trạng thái đột biến Bạn có thể sử dụng 4 để thay thế một mục cũ bằng phiên bản cập nhật của nó mà không bị thay đổi 3Ở đây, import { useState } from 'react'; let initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [artists, setArtists] = useState( initialArtists ); return ( <> <h1>Inspiring sculptors:h1> <ul> {artists.map(artist => ( <li key={artist.id}> {artist.name}{' '} <button onClick={() => { setArtists( artists.filter(a => a.id !== artist.id ) ); }}> Delete button> li> ))} ul> > ); }4 là cú pháp lây lan đối tượng được sử dụng để Với phương pháp này, không có mục trạng thái hiện có nào bị thay đổi và lỗi đã được sửa Ứng dụng. js Ứng dụng. jsĐặt lại Ngã ba 4Cho xem nhiều hơnNói chung, bạn chỉ nên thay đổi các đối tượng mà bạn vừa tạo. Nếu bạn đang chèn một tác phẩm nghệ thuật mới, bạn có thể thay đổi nó, nhưng nếu bạn đang xử lý thứ gì đó đã có sẵn, bạn cần tạo một bản sao Viết logic cập nhật ngắn gọn với ImmerCập nhật các mảng lồng nhau mà không có đột biến có thể hơi lặp lại.
Đây là ví dụ về Art Bucket List được viết lại bằng Immer Ứng dụng. gói js. json Ứng dụng. jsĐặt lại Ngã ba 5Cho xem nhiều hơnLưu ý cách với Immer, đột biến như import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }5 hiện không sao 6Điều này là do bạn không thay đổi trạng thái ban đầu, nhưng bạn đang thay đổi một đối tượng import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }6 đặc biệt do Immer cung cấp. Tương tự, bạn có thể áp dụng các phương pháp biến đổi như 9 và import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState([]); return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setName(''); setArtists([ ...artists, { id: nextId++, name: name } ]); }}>Addbutton> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }0 cho nội dung của import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }6 Đằng sau hậu trường, Immer luôn xây dựng trạng thái tiếp theo từ đầu theo những thay đổi mà bạn đã thực hiện đối với import { useState } from 'react'; let nextId = 3; const initialArtists = [ { id: 0, name: 'Marta Colvin Andrade' }, { id: 1, name: 'Lamidi Olonade Fakeye'}, { id: 2, name: 'Louise Nevelson'}, ]; export default function List() { const [name, setName] = useState(''); const [artists, setArtists] = useState( initialArtists ); function handleClick() { const insertAt = 1; // Could be any index const nextArtists = [ // Items before the insertion point: ...artists.slice(0, insertAt), // New item: { id: nextId++, name: name }, // Items after the insertion point: ...artists.slice(insertAt) ]; setArtists(nextArtists); setName(''); } return ( <> <h1>Inspiring sculptors:h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={handleClick}> Insert button> <ul> {artists.map(artist => ( <li key={artist.id}>{artist.name}li> ))} ul> > ); }6. Điều này giữ cho trình xử lý sự kiện của bạn rất ngắn gọn mà không bao giờ thay đổi trạng thái Tóm tắt lại
Hãy thử một số thử thách1. Cập nhật một mặt hàng trong giỏ hàng2. Xóa một mặt hàng khỏi giỏ hàng3. Sửa các đột biến bằng các phương pháp không đột biến4. Sửa các đột biến bằng cách sử dụng Immer Làm cách nào để cập nhật giá trị trong mảng đối tượng JavaScript?Để cập nhật một đối tượng trong một mảng JavaScript, bạn có thể sử dụng phương thức findIndex() để thực thi từng phần tử mảng và cập nhật các giá trị đối tượng tương ứng .
Làm cách nào để thay đổi giá trị trong đối tượng JavaScript?Để cập nhật tất cả các giá trị trong một đối tượng, cách dễ nhất là. . Sử dụng đối tượng. keys để lấy tất cả các key của đối tượng Áp dụng bất kỳ logic nào để quyết định giá trị nào sẽ được cập nhật Cập nhật giá trị của từng giá trị bằng vòng lặp như forEach hoặc for |