Liên kết Input với Mảng trong React
Giả sử trong state notes lưu trữ một mảng:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
</div>;
}
Giả sử chúng ta cũng có một hàm hỗ trợ, tính tổng các phần tử của mảng:
function getSum(arr) {
let sum = 0;
for (const elem of arr) {
sum += +elem;
}
return sum;
}
function App() {
...
}
Hãy tính và hiển thị tổng các phần tử của mảng từ state, sử dụng hàm hỗ trợ của chúng ta:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
{getSum(notes)}
</div>;
}
Bây giờ hãy tạo ba input và trong value
của mỗi input, ghi một phần tử của mảng:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
<input value={notes[0]} />
<input value={notes[1]} />
<input value={notes[2]} />
{getSum(notes)}
</div>;
}
Bây giờ hãy thêm sự kiện onChange
vào các input của chúng ta. Đồng thời tạo một hàm xử lý chung
duy nhất cho sự kiện này:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
// hàm xử lý chung
}
return <div>
<input value={notes[0]} onChange={event => changeHandler(0, event)} />
<input value={notes[1]} onChange={event => changeHandler(1, event)} />
<input value={notes[2]} onChange={event => changeHandler(2, event)} />
{getSum(notes)}
</div>;
}
Như bạn thấy, hàm changeHandler
nhận tham số đầu tiên là chỉ số của phần tử
mảng mà input này đang chỉnh sửa.
Dựa vào chỉ số này, chúng ta có thể thay thế phần tử mảng bằng nội dung của input.
Hãy thực hiện điều đó:
function changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
Bây giờ có thể chỉnh sửa bất kỳ input nào, đồng thời mảng sẽ thay đổi một cách phản ứng (reactive) và, tương ứng, tổng các phần tử của nó sẽ được tính lại.
Hãy tập hợp toàn bộ mã của chúng ta lại:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
return <div>
<input value={notes[0]} onChange={event => changeHandler(0, event)} />
<input value={notes[1]} onChange={event => changeHandler(1, event)} />
<input value={notes[2]} onChange={event => changeHandler(2, event)} />
{getSum(notes)}
</div>;
}
Có thể làm sao cho các input được tạo ra trong một vòng lặp:
function App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
const result = notes.map((note, index) => {
return <input
key={index}
value={note}
onChange={event => changeHandler(index, event)}
/>;
});
return <div>
{result}
{getSum(notes)}
</div>;
}
Cho mảng sau:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Hiển thị trên màn hình giá trị trung bình cộng của các phần tử mảng này. Trong một vòng lặp, hãy tạo các input để chỉnh sửa các phần tử.