리액트 훅 내의 오브젝트 배열에서 상태 'onChange'를 업데이트하려면 어떻게 해야 합니까?
다음을 사용하여 저장된 데이터를 검색했습니다.useState
오브젝트 배열에서 데이터는 폼필드로 출력됩니다.이제 입력 시 필드(상태)를 업데이트할 수 있습니다.
사람들이 배열된 속성의 상태를 업데이트하는 예를 본 적이 있지만, 배열된 개체의 상태에 대해서는 본 적이 없기 때문에 어떻게 해야 할지 모르겠습니다.오브젝트 인덱스를 콜백 함수로 전달받았는데 그것을 사용하여 상태를 갱신하는 방법을 알 수 없었습니다.
// sample data structure
const datas = [
{
id: 1,
name: 'john',
gender: 'm'
}
{
id: 2,
name: 'mary',
gender: 'f'
}
]
const [datas, setDatas] = useState([]);
const updateFieldChanged = index => e => {
console.log('index: ' + index);
console.log('property name: '+ e.target.name);
setData() // ??
}
return (
<React.Fragment>
{datas.map((data, index) => {
<li key={data.name}>
<input type="text" name="name" value={data.name} onChange={updateFieldChanged(index)} />
</li>
})}
</React.Fragment>
)
방법은 다음과 같습니다.
// sample data structure
/* const data = [
{
id: 1,
name: 'john',
gender: 'm'
}
{
id: 2,
name: 'mary',
gender: 'f'
}
] */ // make sure to set the default value in the useState call (I already fixed it)
const [data, setData] = useState([
{
id: 1,
name: 'john',
gender: 'm'
}
{
id: 2,
name: 'mary',
gender: 'f'
}
]);
const updateFieldChanged = index => e => {
console.log('index: ' + index);
console.log('property name: '+ e.target.name);
let newArr = [...data]; // copying the old datas array
// a deep copy is not needed as we are overriding the whole object below, and not setting a property of it. this does not mutate the state.
newArr[index] = e.target.value; // replace e.target.value with whatever you want to change it to
setData(newArr);
}
return (
<React.Fragment>
{data.map((datum, index) => {
<li key={datum.name}>
<input type="text" name="name" value={datum.name} onChange={updateFieldChanged(index)} />
</li>
})}
</React.Fragment>
)
인정된 답변은 개발자가 소스 시퀀스를 변형시킬 수 있는 중대한 위험을 초래합니다.코멘트는 다음과 같습니다.
let newArr = [...data];
// oops! newArr[index] is in both newArr and data
// this might cause nasty bugs in React.
newArr[index][propertyName] = e.target.value;
즉, 경우에 따라서는 React가 변경 내용을 선택하여 렌더링하지 않을 수 있습니다.
이 작업을 수행하려면 오래된 어레이를 새 어레이로 매핑하고 변경하려는 항목을 업데이트한 항목으로 바꿉니다.
setDatas(
datas.map(item =>
item.id === index
? {...item, someProp : "changed"}
: item
))
setDatas(datas=>({
...datas,
[index]: e.target.value
}))
인덱스가 목표 위치이고 e.target.value가 새 값인 경우
인덱스(원하는 경우 키 제외)를 사용할 필요도 없고 오래된 데이터 어레이를 복사할 필요도 없습니다.또한 updateFieldChanged가 인라인 상태가 아닌 것을 원할 경우 인라인 방식으로 데이터를 전송하거나 인수로서 데이터를 전달할 수도 있습니다.이 방법은 매우 신속하게 이루어집니다.
const initial_data = [
{
id: 1,
name: "john",
gender: "m",
},
{
id: 2,
name: "mary",
gender: "f",
},
];
const [datas, setDatas] = useState(initial_data);
return (
<div>
{datas.map((data, index) => (
<li key={index}>
<input
type="text"
value={data.name}
onChange={(e) => {
data.name = e.target.value;
setDatas([...datas]);
}}
/>
</li>
))}
</div>
);
};
제가 하는 일은 이렇습니다.
const [datas, setDatas] = useState([
{
id: 1,
name: "john",
gender: "m",
},
{
id: 2,
name: "mary",
gender: "f",
},
]);
const updateFieldChanged = (name, index) => (event) => {
let newArr = datas.map((item, i) => {
if (index == i) {
return { ...item, [name]: event.target.value };
} else {
return item;
}
});
setDatas(newArr);
};
return (
<React.Fragment>
{datas.map((data, index) => {
<li key={data.name}>
<input
type="text"
name="name"
value={data.name}
onChange={updateFieldChanged("name", index)}
/>
</li>;
<li key={data.gender}>
<input
type="text"
name="gender"
value={data.gender}
onChange={updateFieldChanged("gender", index)}
/>
</li>;
})}
</React.Fragment>
);
그 전에 어레이를 펼치세요.useState에 의해 반환된 메서드를 사용하지 않으면 훅을 직접 갱신할 수 없기 때문에
const newState = [...originalState]
newState[index] = newValue
setOriginalState(newState)
그러면 상태 값이 변경되고 문자열 배열인 경우 useState 훅이 업데이트됩니다.
const updateFieldChanged = index => e => {
name=e.target.name //key
let newArr = [...data]; // copying the old datas array
newArr[index][name] = e.target.value; //key and value
setData(newArr);
}
return (
<React.Fragment>
{data.map((datum, index) => {
<li key={datum.name}>
<input type="text" name="name" value={datum.name} onChange={updateFieldChanged(index)} />
</li>
})}
</React.Fragment>
)
const [datas, setDatas] = useState([ { id: 1, name: 'john', gender: 'm' } { id: 2, name: 'mary', gender: 'f' } ]);
const updateFieldChanged = (index, e) => { const updateData = { ...data[index], name: e.target.name }
setData([...data.slice(0, index), updateData, ...data.slice(index + 1)]) }
답장이 늦었지만 저도 같은 문제가 있어서 이 문의를 통해 해결하게 되었습니다.도움이 될 수 있으면 확인해 보세요.예를 들어 OrderList라는 이름의 스테이트가 있기 때문에 그 세터는 SetOrderList입니다.목록 내의 특정 레코드를 갱신하려면 SetOrderList를 사용하여 변경해야 할 목록과 맵 함수를 전달하기 위해 목록의 색인 또는 ID를 비교하고 일치하는 특정 레코드를 변경합니다.
const Action = (Id, Status) => { //`enter code here`Call this function onChange or onClick event
setorderList([...orderList.map((order) =>
order.id === Id ? { ...order, status: Status } : order
),
]);
}
인덱스를 기반으로 값을 업데이트하고 for loop을 기준으로 입력을 생성하는 완전한 예...
import React, { useState,useEffect } from "react";
export default function App() {
const [datas, setDatas] =useState([])
useEffect(() => {
console.log("datas");
console.log(datas);
}, [datas]);
const onchangeInput = (val, index) =>{
setDatas(datas=>({
...datas,
[index]: val.target.value
}))
console.log(datas);
}
return (
<>
{
(() => {
const inputs = [];
for (let i = 0; i < 20; i++){
console.log(i);
inputs.push(<input key={i} onChange={(val)=>{onchangeInput(val,i)}} />);
}
return inputs;
})()
}
</>
);
}
const MyCount = () =>{
const myData = [
{
id: 1,
name: 'john',
gender: 'm'
},
{
id: 2,
name: 'mary',
gender: 'f'
}
]
const [count, setCount] = useState(0);
const [datas, setDatas] = useState(myData);
const clkBtn = () =>{
setCount((c) => c + 1);
}
return(
<div>
<button onClick={clkBtn}>+ {count}</button>
{datas.map((data, index) => (
<li key={index}>
<input
type="text"
value={data.name}
onChange={(e) => {
data.name = e.target.value;
setDatas([...datas]);
}}
/>
</li>
))}
</div>
)
}
@Steffan을 기반으로 하여 다음과 같이 사용합니다.
const [arr,arrSet] = useState(array_value);
...
let newArr = [...arr];
arr.map((data,index) => {
newArr[index].somename= new_value;
});
arrSet(newArr);
useEffect를 사용하여 새 arr 값을 확인합니다.
파티에는 조금 늦었지만 어레이의 내용을 새로운 오브젝트에 분산시킨 후 선택한 인덱스에서 원하는 오브젝트를 대체하여 최종적으로 어레이를 생성하는 옵션입니다.이것은 간단한 답변입니다.대형 어레이에는 적합하지 않을 수 있습니다.
// data = [{name: 'tom', age: 15, etc...}, {name: 'jerry', age: 10, etc...}]
// index = 1
setData(Object.values({...data, [index]: {...data[index], name: 'the mouse' }}))
// data = [{name: 'tom', age: 15, etc...}, {name: 'the mouse', age: 10, etc...}]
언급URL : https://stackoverflow.com/questions/55987953/how-do-i-update-states-onchange-in-an-array-of-object-in-react-hooks
'source' 카테고리의 다른 글
Spring Boot에서 Logback이 기본 로깅 프레임워크인 이유는 무엇입니까? (0) | 2023.02.26 |
---|---|
React Native의 어레이 맵 함수에서 동적으로 콘텐츠 렌더링 (0) | 2023.02.26 |
JSON 스키마의 "필수"와 "옵션"의 차이점은 무엇입니까? (0) | 2023.02.17 |
파일과 함께 로컬로 로드된 모바일 WebView에서 CORS cookie 자격 정보:// (0) | 2023.02.17 |
JSON을 사용한 시리얼화된 필드의 순서.그물 (0) | 2023.02.17 |