[javascript] React Hooks useState () with Object

React with Hooks에서 상태를 업데이트하는 올바른 방법은 무엇입니까?

export Example = () => {
  const [exampleState, setExampleState] = useState(
  {masterField: {
        fieldOne: "a",
        fieldTwo: {
           fieldTwoOne: "b"
           fieldTwoTwo: "c"
           }
        }
   })

한 사람이 어떻게 사용하는 것이 setExampleState업데이 트에 exampleStatea(AN 필드를 추가)?

const a = {
masterField: {
        fieldOne: "a",
        fieldTwo: {
           fieldTwoOne: "b",
           fieldTwoTwo: "c"
           }
        },
  masterField2: {
        fieldOne: "c",
        fieldTwo: {
           fieldTwoOne: "d",
           fieldTwoTwo: "e"
           }
        },
   }
}

b (값 변경)?

const b = {masterField: {
        fieldOne: "e",
        fieldTwo: {
           fieldTwoOne: "f"
           fieldTwoTwo: "g"
           }
        }
   })



답변

이렇게 새로운 값을 전달할 수 있습니다.

  setExampleState({...exampleState,  masterField2: {
        fieldOne: "c",
        fieldTwo: {
           fieldTwoOne: "d",
           fieldTwoTwo: "e"
           }
        },
   }})


답변

누군가 useState ()를 검색하는 경우 객체에 대한 후크 업데이트

- Through Input

        const [state, setState] = useState({ fName: "", lName: "" });
        const handleChange = e => {
            const { name, value } = e.target;
            setState(prevState => ({
                ...prevState,
                [name]: value
            }));
        };

        <input
            value={state.fName}
            type="text"
            onChange={handleChange}
            name="fName"
        />
        <input
            value={state.lName}
            type="text"
            onChange={handleChange}
            name="lName"
        />
   ***************************

 - Through onSubmit or button click

        setState(prevState => ({
            ...prevState,
            fName: 'your updated value here'
         }));


답변

일반적으로 React 상태에서 깊이 중첩 된 객체를주의해야합니다. 예기치 않은 동작을 방지하려면 상태를 변경없이 업데이트해야합니다. 딥 오브젝트가 있으면 불변성을 위해 딥 클로닝을하게되는데 이는 React에서 상당히 비쌀 수 있습니다. 왜?

상태를 딥 복제하면 React는 변수가 변경되지 않았더라도 변수에 의존하는 모든 것을 다시 계산하고 다시 렌더링합니다!

따라서 문제를 해결하기 전에 먼저 상태를 평평하게 할 수있는 방법을 생각하십시오. 그렇게하면 useReducer ()와 같은 큰 상태를 처리하는 데 도움이되는 멋진 도구를 찾을 수 있습니다.

그것에 대해 생각했지만 여전히 깊게 중첩 된 상태 트리를 사용해야한다고 확신하는 경우 immutable.jsImmutability-helper 와 같은 라이브러리에서 useState ()를 사용할 수 있습니다 . 변경 가능성에 대해 걱정할 필요없이 딥 오브젝트를 간단하게 업데이트하거나 복제 할 수 있습니다.


답변

필립 덕분에 도움이되었습니다-제 사용 사례는 입력 필드가 많은 양식을 가지고 있었기 때문에 초기 상태를 객체로 유지하고 객체 상태를 업데이트 할 수 없었습니다. 위의 게시물이 도움이되었습니다 🙂

const [projectGroupDetails, setProjectGroupDetails] = useState({
    "projectGroupId": "",
    "projectGroup": "DDD",
    "project-id": "",
    "appd-ui": "",
    "appd-node": ""
});

const inputGroupChangeHandler = (event) => {
    setProjectGroupDetails((prevState) => ({
       ...prevState,
       [event.target.id]: event.target.value
    }));
}

<Input
    id="projectGroupId"
    labelText="Project Group Id"
    value={projectGroupDetails.projectGroupId}
    onChange={inputGroupChangeHandler}
/>



답변

파티에 늦었어요 .. 🙂

@aseferov 대답은 전체 개체 구조를 다시 입력하려는 경우 매우 잘 작동합니다. 그러나 목표 / 목표가 Object의 특정 필드 값을 업데이트하는 것이라면 아래 접근 방식이 더 낫다고 생각합니다.

상태:

const [infoData, setInfoData] = useState({
    major: {
      name: "John Doe",
      age: "24",
      sex: "M",
    },

    minor:{
      id: 4,
      collegeRegion: "south",

    }

  });

특정 기록을 업데이트하려면 이전 주를 리콜해야합니다. prevState

여기:

setInfoData((prevState) => ({
      ...prevState,
      major: {
        ...prevState.major,
        name: "Tan Long",
      }
    }));

혹시

setInfoData((prevState) => ({
      ...prevState,
      major: {
        ...prevState.major,
        name: "Tan Long",
      },
      minor: {
        ...prevState.minor,
        collegeRegion: "northEast"

    }));

나는 이것이 비슷한 문제를 해결하려는 모든 사람에게 도움이되기를 바랍니다.


답변

function App() {

  const [todos, setTodos] = useState([
    { id: 1, title: "Selectus aut autem", completed: false },
    { id: 2, title: "Luis ut nam facilis et officia qui", completed: false },
    { id: 3, title: "Fugiat veniam minus", completed: false },
    { id: 4, title: "Aet porro tempora", completed: true },
    { id: 5, title: "Laboriosam mollitia et enim quasi", completed: false }
  ]);

  const changeInput = (e) => {todos.map(items => items.id === parseInt(e.target.value) && (items.completed = e.target.checked));
 setTodos([...todos], todos);}
  return (
    <div className="container">
      {todos.map(items => {
        return (
          <div key={items.id}>
            <label>
<input type="checkbox"
onChange={changeInput}
value={items.id}
checked={items.completed} />&nbsp; {items.title}</label>
          </div>
        )
      })}
    </div>
  );
}


답변

최고의 솔루션은 Immer 라고 생각 합니다. 필드를 직접 수정하는 것처럼 개체를 업데이트 할 수 있습니다 (masterField.fieldOne.fieldx = ‘abc’). 그러나 물론 실제 대상을 변경하지는 않습니다. 초안 개체의 모든 업데이트를 수집하고 마지막에 원본 개체를 대체하는 데 사용할 수있는 최종 개체를 제공합니다.