programing

리액트 훅을 사용하여 소품을 상태와 동기화하는 방법: setState()

lastmoon 2023. 2. 26. 10:27
반응형

리액트 훅을 사용하여 소품을 상태와 동기화하는 방법: setState()

컴포넌트가 받는 소품을 사용하여 React hook setState()를 사용하여 상태를 설정하려고 합니다.다음 코드를 사용해 보았습니다.

import React,{useState , useEffect} from 'react';

const Persons = (props) =>  {

    // console.log(props.name);

   const [nameState , setNameState] = useState(props)

   console.log(nameState.name);
   console.log(props.name);
 
   return (
            <div>
                <p>My name is {props.name} and my age is {props.age}</p>
                <p>My profession is {props.profession}</p>
            </div>
        )

}

export default Persons;

이 문제는 컴포넌트가 로드되었을 때 상태가 설정되고 있다는 것입니다.하지만 새로운 소품을 받았을 때 상태는 업데이트되지 않습니다.이 경우 상태를 업데이트하려면 어떻게 해야 합니까?

useStatehooks 함수 인수는 프로펠이 변경될 때마다 사용되지 않고 한 번만 사용됩니다.을 활용해야 합니다.useEffect훅을 사용하여 소위 말하는componentWillReceiveProps/getDerivedStateFromProps기능성

import React,{useState , useEffect} from 'react';

const Persons = (props) =>  {
   const [nameState , setNameState] = useState(props)

   useEffect(() => {
       setNameState(props);
   }, [props])

   return (
            <div>
                <p>My name is {props.name} and my age is {props.age}</p>
                <p>My profession is {props.profession}</p>
            </div>
        )

}

export default Persons;

props에 가치를 두다.useState(props)초기 렌더링 중에만 사용되며 추가 상태 업데이트는 설정기를 사용하여 수행됩니다.setNameState.

또, 다음의 조작은 불필요합니다.useEffect파생 상태를 업데이트할 때:

const Person = props => {
  const [nameState, setNameState] = useState(props.name);
  // update derived state conditionally without useEffect
  if (props.name !== nameState) setNameState(props.name);
  // ... other render code
};

React 문서에서:

[...] 렌더링 에 바로 상태업데이트할 수 있습니다.React는 첫 번째 렌더 종료 후 즉시 업데이트된 상태로 컴포넌트를 재실행하므로 비용이 많이 들지 않습니다.

[...] 렌더링 중 업데이트는 개념적으로 항상 그래왔던 것과 동일합니다.

기본적으로 다음과 같이 브라우저 재도장 단계를 추가로 생략함으로써 성능을 최적화할 수 있습니다.useEffect렌더가 화면에 커밋된 후 항상 실행됩니다.

작업 예

이것은, 상기의 패턴을 나타내는 작위적인 예입니다.실제 코드에서는 읽을 수 있습니다.props.name직접적으로.보다 적절한 파생 상태 사용 사례는 React 블로그 게시물을 참조하십시오.

const Person = props => {
  const [nameState, setNameState] = React.useState(props.name);
  // Here, we update derived state without useEffect
  if (props.name !== nameState) setNameState(props.name);

  return (
    <p>
      <h3>Person</h3>
      <div>{nameState} (from derived state)</div>
      <div>{props.name} (from props)</div>
      <p>Note: Derived state is synchronized/contains same value as props.name</p>
    </p>
  );
};

const App = () => {
  const [personName, setPersonName] = React.useState("Lui");
  const changeName = () => setPersonName(personName === "Lukas" ? "Lui" : "Lukas");

  return (
    <div>
      <Person name={personName} />
      <button onClick={changeName}>Change props</button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>

다음과 같은 일반적인 아이디어를 적용할 수 있습니다.

export function useStateFromProp(initialValue) {
  const [value, setValue] = useState(initialValue);

  useEffect(() => setValue(initialValue), [initialValue]);

  return [value, setValue];
}


function MyComponent({ value: initialValue }) {
  const [value, setValue] = useStateFromProp(initialValue);

  return (...);
}

그러기 위해서는,useEffect그래서 네 코드는 뭐랄까.프로가 변경되지 않은 경우 다시 렌더링하지 않으려면 먼저 useEffect를 확인한 후 소품을 현재 변수로 설정해야 합니다.

import React, { useState, useEffect } from "react";

const Persons = props => {
  // console.log(props.name);

  const [nameState, setNameState] = useState(props);

  console.log(nameState.name);
  console.log(props.name);
  useEffect(
    () => {
      if (nameState !== props.name) {
        setNameState(props.name);
      }
    },
    [nameState]
  );
  return (
    <div>
      <p>
        My name is {props.name} and my age is {props.age}
      </p>
      <p>My profession is {props.profession}</p>
    </div>
  );
};

export default Persons;

데모

import React, { useState, useEffect } from "react";

const Persons = props => {
  // console.log(props.name);

  const [nameState, setNameState] = useState(props);

  console.log(nameState.name);
  console.log(props.name);
  useEffect(
    () => {
      if (nameState !== props) {
        setNameState(props);
      }
    },
    [nameState]
  );
  return (
    <div>
      <p>
        My name is {props.name} and my age is {props.age}
      </p>
      <p>My profession is {props.profession}</p>
    </div>
  );
};

export default Persons;

Hooks react 문서에 따르면 소품이나 컴포넌트에 업데이트가 있을 때는 항상 useEffect가 호출됩니다.따라서 useState를 업데이트하기 전에 상태를 확인한 후 지속적으로 재렌더링을 하지 않도록 값을 업데이트해야 합니다.

다른 해결책을 찾아냈어useEffect대신 두 개를 사용합니다.useStates. 커스텀 훅에 넣었습니다.

export function useStateFromProp(propValue) {
  const [value,          setValue         ] = useState(propValue);
  const [propValueState, setPropValueState] = useState(propValue);

  if (propValueState != propValue) {
    setPropValueState(propValue);
    setValue(propValue);
  }

  return [value, setValue];
}


function MyComponent({ value: propValue }) {
  const [value, setValue] = useStateFromProp(propValue);

  return (...);
}

주요 이점은 현재 정상적으로 트리거된 재렌더가 다음과 같은 경우입니다.useEffect아이 컴포넌트가 재검출되기 전에 발생하므로 이 방법이 더 빠를 것입니다.

면책사항:나는 아직 이것을 테스트하지 않았다.구글을 검색해 보니 https://pretagteam.com/question/in-react-hooks-when-calling-setstate-directly-during-render-is-the-rerender-guaranteed-to-run-before-the-render-of-children이라는 지원 기사를 발견했습니다.

추가 렌더 없이 소품 및 기타 상태에서 상태를 계산해야 하는 경우 다음을 고려하십시오.

a) 용용법 a a를 사용하다useMemo

const Component = ({ name }) => {
  const [surname, setSurname] = useState('');

  const fullName = useMemo(() => {
     return name + ' ' + surname;
  }, [name, surname])

  ...
}

b) 매우 무겁지 않은 경우 내부 렌더 계산:

const Component = ({ name }) => {
  const [surname, setSurname] = useState('');

  const fullName = name + ' ' + surname;

  ...
}

c) 기존 소품을 비교하고 다른 장소에서 상태를 갱신할 수 있어야 하는 어려운 경우, 겉보기에는 좋지 않지만 다음과 같습니다.

const Component = ({ name }) => {
  const prevNameRef = useRef()
  const derivedState = useRef();

  if (prevNameRef.current !== name) {
    derivedState.current = ...
    prevNameRef.current = name;
  }
 
  // some other place
  derivedState.current = ...
}

이 문제는 하나의 개념 변수 또는 변수 집합을 사용하여 두 가지 다른 작업을 수행하려는 시도를 의미한다고 생각합니다.예를 들어, 데이터 수집을 위해props.name ★★★★★★★★★★★★★★★★★」name같은 일을 하게끔 말이야

그래서 만약에

const [name, setName] = useState(props.name)

부족하고 하려고 .props.name variable " " "로 변환됩니다.name에서는, 「이러한 것은 아니다」라고 하는 경우가 있습니다.name과부하가 걸리고 있습니다.다른 상태 변수(예: )를 설정해 보십시오. updatedName일이 잘 풀리는지 알아봐야지

원래 예에서는 상태 변수가 로그 문 이외에는 사용되지 않기 때문에 이 문제가 발생하지 않습니다.

ifconst [name, setName] = useState(props.name)되는 경우 상태 updated updated updated 시 、 시트 、 updated updated 、 updated updated 、 updated updated updated updated updated updated updated updated 。name props.name(또한 변경을 시도하면 재검토의 원인이 됩니다).

언급URL : https://stackoverflow.com/questions/54625831/how-to-sync-props-to-state-using-react-hooks-setstate

반응형