반응 상태에 대해 알아야 할 것

너는 반응 상태가 무엇인지, 그리고 도구와의 차이를 알 수 있다.그런데 이 모든 걸 알고 있나?
본고에서 우리는 Class component에서 Functional component 사이의 상태를 어떻게 사용하는지 이해하고 주의사항을 제시하고자 한다...

이게 어떻게 된 일입니까?
특히 React 구성 요소에 상호작용을 추가하기를 원할 수도 있습니다.이러한 상호작용은 UI를 바꿀 수 있다. 이런 상황에서 데이터를 React 상태에 저장하고 그 기능의 표현 방식을 바꿀 수 있다.props과 달리 구성 요소는 상태를 변경할 수 있습니다.그러나 상태를 변경할 때 구성 요소를 다시 보여주려면 몇 가지 규칙을 따라야 한다.어디 보자.

클래스 구성 요소
네가 지금 알고 있는 것에 들어가기 전에, 예를 들면 갈고리.갈고리가 존재하지 않는 시대였다. 상태 구성 요소를 가진 유일한 방법은 구성 요소 종류를 사용하는 것이다.

Note: It's in the version 16.8.6 of React that hooks has been exposed by the library.

Component class을 만드는 방법은 class을 만들고 React.Component 클래스를 확장한 다음 라이프 사이클 메소드에 액세스할 수 있습니다.
  • constructor
  • componentDidMount
  • componentDidUpdate
  • render(필수)
  • componentWillUnmount
  • import React from "react";
    
    class MyClassComponent extends React.Component {
      render() {
        return <p>A simple class component</p>;
      }
    }
    

    초기화
    그런 다음 두 가지 방법으로 상태를 초기화할 수 있습니다.
  • 인치 constructor
  • class MyClassComponent extends React.Component {
      constructor() {
        this.state = {
          firstName: "Bob",
          lastName: "TheSponge",
        };
      }
      render() {
        return <p>A simple class component with a state</p>;
      }
    }
    
  • 재산 직접 성명 state
  • class MyClassComponent extends React.Component {
      state = {
        firstName: "Bob",
        lastName: "TheSponge",
      };
    
      render() {
        return <p>A simple class component with a state</p>;
      }
    }
    

    Note: You can use both as you wish. It's the same. But constructor will give you the possibility to use props to initialize the state.



    국가에 들어가다
    예상대로 이제 this.state을 사용하여 주에 액세스할 수 있습니다.
    class MyClassComponent extends React.Component {
      state = {
        firstName: "Bob",
        lastName: "TheSponge",
      };
    
      render() {
        return (
          <div>
            <p>First name: {this.state.firstName}</p>
            <p>Last name: {this.state.lastName}</p>
          </div>
        );
      }
    }
    

    상태 업데이트
    만약 state이 업데이트된 적이 없다면, 이 데이터를 저장할 상태가 필요하지 않을 수도 있습니다.
    업데이트하려면 구성 요소 실례 setState에서 접근 방법 this의 상태를 찾을 수 있습니다.
    그리고 너는 이 주의 어떤 일도 바꿀 수 있다.setState에 대해 알아야 할 사항useState의 구성 요소 클래스와 달리 setState은 업데이트된 데이터를 이전 데이터와 자동으로 결합합니다.
    class MyClassComponent extends React.Component {
      state = {
        firstName: "Bob",
        lastName: "TheSponge",
      };
    
      updateFirstName = () => {
        // It will result having a state with
        // { firstName: 'New firstName', lastName: 'TheSponge' }
        this.setState({ firstName: "New firstName" });
      };
    
      render() {
        const { firstName, lastName } = this.state;
    
        return (
          <div>
            <p>First name: {firstName}</p>
            <p>Last name: {lastName}</p>
            <button
              type="button"
              onClick={this.updateFirstName}
            >
              Update firstName
            </button>
          </div>
        );
      }
    }
    

    Warning: It will not deeply merge. Just shallow stuff. If you need to update a single key of an object store in a state, you will have to update it in function of the previous object stored.



    이전 함수의 상태 업데이트
    위에서 경고한 바와 같이 당신이 생각하기에
  • 업데이트 상태가
  • 인 객체의 일부
  • 은 이전 기능(예: 카운터)
  • 의 상태만 업데이트하면 됩니다.
    그런 다음 setState 함수의 다른 API를 사용합니다.
    Yep setState
  • 뉴저지
  • 은 매개 변수로 리셋을 전달하고 새로운 상태로 되돌려줍니다
  • class MyClassComponent extends React.Component {
      state = {
        counter: 0,
      };
    
      incrementCounter = () => {
        this.setState((prevState) => ({
          counter: prevState.counter + 1,
        }));
      };
    
      render() {
        return (
          <button type="button" onClick={this.incrementCounter}>
            Increment: {this.state.counter}
          </button>
        );
      }
    }
    

    Note: In this case state will be "shallowly" merged too.


    너는 아마도 자신에게 이렇게 하는 것은 너무 지나치다고 말할 것이다. 왜냐하면 나는 counter으로 이전의 this.state.counter을 방문할 수 있기 때문이다
    네, 네 말이 맞아요.하지만 당신은:
  • 상태를 연속으로 여러 번 업데이트하는 동일한 속성:
  • class MyClassComponent extends React.Component {
      state = {
        counter: 0,
      };
    
      // This will only increment by 1 because when calling the
      // the value of `this.state.counter` is 0
      // for all 3 `setState`
      incrementByThreeCounter = () => {
        this.setState({
          counter: this.state.counter + 1,
        });
        this.setState({
          counter: this.state.counter + 1,
        });
        this.setState({
          counter: this.state.counter + 1,
        });
      };
    
      render() {
        return (
          <button
            type="button"
            onClick={this.incrementByThreeCounter}
          >
            Increment: {this.state.counter}
          </button>
        );
      }
    }
    
  • 비동기식 컨텐츠 처리
  • class FoodOrdering extends React.Component {
      state = {
        orderInProgressCount: 0,
        orderDeliveredCount: 0,
      };
    
      order = async () => {
        // I tell myself that I can destructure
        // `loading` from the state because it used at multiple place
        // but it's a bad idea
        const { orderInProgressCount, orderDeliveredCount } =
          this.state;
        this.setState({
          orderInProgressCount: orderInProgressCount + 1,
        });
        await fakeAPI();
        // In this case `loading` is still false
        this.setState({
          orderInProgressCount: orderInProgressCount - 1,
          orderDeliveredCount: orderDeliveredCount + 1,
        });
      };
    
      render() {
        const { orderInProgressCount, orderDeliveredCount } =
          this.state;
    
        return (
          <div>
            <p>Order in progress: {orderInProgressCount}</p>
            <p>Order delivered: {orderDeliveredCount}</p>
            <button type="button" onClick={this.order}>
              Order food
            </button>
          </div>
        );
      }
    }
    
    여기서 놀기:
    따라서 이전 값이 필요할 때 콜백 API를 사용하는 것이 좋습니다.
    우리는 이미 구성 요소 종류를 충분히 놀았으니, 이제 기능 구성 요소에서 어떻게 사용하는지 봅시다.

    기능 부품16.8.6 버전에서는 useState이 연결되어 있어 상태가 있는 기능 구성 요소를 실현할 수 있다.우리 함께 그것을 어떻게 사용하는지 검사합시다.

    초기화
    상태의 초기 값은 useState 갈고리에 매개 변수로 제공됩니다.다음과 같은 두 가지 방법이 있습니다.
  • 직접 제공
  • import { useState } from "react";
    
    function StateFunctionalComponent() {
      // The initial value is 0
      useState(0);
    
      return <p>Functional component with state</p>;
    }
    
  • 은 지연 초기화를 위한 리콜을 제공합니다.
  • import { useState } from "react";
    
    function initializeState() {
      return 0;
    }
    
    function StateFunctionalComponent() {
      // The initial value will be
      // initialized in a lazy way to 0
      useState(initializeState);
    
      return <p>Functional component with state</p>;
    }
    
    아래의 초기화는 당신에게 어떤 차이가 있습니까?
    useState(initializeState());
    

    useState(initializeState);
    
    뚜렷하지 않죠?
    사실상 첫 번째 코드에서는 initializeState이 렌더링할 때마다 호출되고 두 번째 코드는 첫 번째 렌더링에서만 호출된다.
    고성능 프로세스가 있을 때, 지연 초기화를 사용하면 재미있을 수 있습니다.

    어떻게 국가에 들어갑니까
    어떻게 방문하는지 알고 싶으면, 우리는 반드시 useState이 되돌아오는 내용을 보아야 한다.
    값이 첫 번째 요소이고 업데이트 프로그램이 두 번째 요소인 배열을 반환합니다.
    const [value, setValue] = useState('Initial value');
    
    그래서 저는 value만 사용하면 됩니다.

    Note: You can name the value and the updater with the name you want, because there is a destructuring of the array :)


    const [counter, setCounter] = useState(0);
    

    상태 업데이트
    그리고 상태를 갱신하려면 updater을 사용하세요.*Component 클래스와 마찬가지로 다음 두 가지 방법이 있습니다.
  • 직접 전달치
  • function Counter() {
      const [counter, setCounter] = useState(0);
    
      return (
        <button type="button" onClick={() => setCounter(100)}>
          Change counter: {counter}
        </button>
      );
    }
    
  • 은 다음과 같은 이전 상태에 액세스할 수 있도록 콜백을 전달합니다.
  • function Counter() {
      const [counter, setCounter] = useState(0);
    
      return (
        <button
          type="button"
          onClick={() => setCounter((prev) => prev + 1)}
        >
          Increment counter: {counter}
        </button>
      );
    }
    
    에서 설명한 것과 같은 이유로 이전 값이 필요할 때 콜백 API를 사용하는 것이 좋습니다.

    기능 구성 요소의 상태에 대해 알아야 할 것

    자동으로 병합이 완료되지 않았습니다.
    함수 구성 요소의 상태를 업데이트할 때 상태를 병합하지 않습니다.따라서 주에 객체가 있는 경우 업데이트 중에 전달되지 않은 모든 키가 삭제됩니다.
    function Person() {
      const [person, setPerson] = useState({
        firstName: "Bob",
        lastName: "TheSponge",
      });
    
      const updateFirstName = () => {
        // When doing that you will lose the lastName key
        // in your person object
        setPerson({ firstName: "Romain" });
      };
    
      return (
        <div>
          <p>First name: {firstName}</p>
          <p>Last name: {lastName}</p>
          <button type="button" onClick={updateFirstName}>
            Update firstName
          </button>
        </div>
      );
    }
    

    함수를 상태에 저장useState의 API는 상태를 초기화하고 업데이트할 때 리셋할 수 있기 때문입니다.함수를 저장하려면 두 프로세스 중 콜백 API를 사용해야 합니다. 그렇지 않으면 함수가 실행되고 반환 값이 저장됩니다.
    function firstFunction() {
      // Do some stuff
      return "Hello";
    }
    
    function secondFunction() {
      // Do some stuff
      return "Guys and girls";
    }
    
    export default function MyComponent() {
      // If you do `useState(firstFunction)`
      // It will be 'Hello' that will be stored
      const [myFunction, setMyFunction] = useState(
        () => firstFunction
      );
    
      const changeFunction = () => {
        // If you do `setMyFunction(secondFunction)`
        // It will be 'Guys and girls' that will be stored
        setMyFunction(() => secondFunction);
      };
    
      return (
        <button type="button" onClick={changeFunction}>
          Change the function stored: {myFunction.toString()}
        </button>
      );
    }
    

    비동기 코드 사용
    대부분의 경우 React는 일괄 처리 상태를 업데이트하여 단일 렌더링을 생성합니다.예를 들어 useEffect/useLayoutEffect과 이벤트 처리 프로그램에서
    예를 들어, 다음 코드에서 버튼을 클릭하면 새 firstNamelastName을 사용하여 단일 렌더링이 생성됩니다.
    function MyComponent() {
      const [firstName, setFirstName] = useState("Bob");
      const [lastName, setLastName] = useState("TheSponge");
    
      return (
        <button
          type="button"
          onClick={() => {
            setFirstName("Patrick");
            setLastName("Star");
          }}
        >
          Change name
        </button>
      );
    }
    
    그러나 비동기식 코드를 사용하는 경우 예를 들어 REST API를 사용하여 새 이름을 가져오면 여러 개의 표현이 발생합니다.
    function fakeAPI() {
      return new Promise((resolve) =>
        setTimeout(
          () =>
            resolve({ firstName: "Patrick", lastName: "Star" }),
          500
        )
      );
    }
    
    function MyComponent() {
      const [firstName, setFirstName] = useState("Bob");
      const [lastName, setLastName] = useState("TheSponge");
    
      return (
        <button
          type="button"
          onClick={async () => {
            const newName = await fakeAPI();
    
            // It will result into 2 render
            // firstName: 'Patrick' and lastName: 'TheSponge'
            // firstName: 'Patrick' and lastName: 'Star'
            setFirstName(newName.firstName);
            setLastName(newName.lastName);
          }}
        >
          Change name
        </button>
      );
    }
    
    이러한 상황에서 우리는 firstNamelastName의 값을 동시에 가지기를 원한다. 왜냐하면 이 값들은 한데 묶여 있기 때문이다.그러나 업데이트된 값은 상관없을 수도 있지만, 우리는 때때로 함께 업데이트를 해야 한다. 이런 상황에서 우리는 단독 상태 업데이트를 실행할 것이며, 상태 업데이트의 순서에 주의해야 한다.

    Note: With React v18 these cases will not happen anymore, and updates will be also batched.

    Note: In a next article, we will see how the batching of state works under the hood and how we can force the batching of updates in an application.



    국가와 무슨 관계가 있는가
    이 규칙은 구성 요소 클래스와 기능 구성 요소에 모두 유효합니다.한 가지 상태를 바꾸지 마라.
    예를 들어, 이렇게 하지 마십시오.
    function Person() {
      const [person, setPerson] = useState({
        firstName: "Bob",
        lastName: "TheSponge",
      });
    
      return (
        <div>
          <p>First name: {firstName}</p>
          <p>Last name: {lastName}</p>
          <button
            type="button"
            onClick={() =>
              setPerson(
                (prevState) => (prevState.firstName = "Romain")
              )
            }
          >
            Update firstName
          </button>
        </div>
      );
    }
    
    왜 안 돼?
    업데이트 리셋을 호출할 때, React는 새로운 상태와 엄격하게 비교되며, 만약 같으면, React는 다시 렌더링을 터치하지 않습니다.

    Note: And do person.firstName = 'Romain' will do nothing at all.



    결론
    React state를 사용하는 것은 어렵지 않으며 이를 제대로 사용하는 방법을 이해하는 것이 중요합니다.
  • 불돌연변이 상태
  • 마지막 값이 필요할 경우
  • 리콜이 포함된 버전을 사용하는 것이 좋습니다
    성능 비용 때문에 성능 구성 요소에서 상태를 초기화하려면 리셋 초기화를 사용하십시오.
    마지막으로 상태가 UI에 사용되지 않으면 state을 사용하는 것이 옳지 않을 수도 있고 ref(useRef)을 사용하는 것이 더 좋은 선택일 수도 있다.다음 기사에서 확인할 수 있습니다.)
    언제든지 의견을 올려주시고 더 많은 정보를 원하신다면 계속해서 저를 팔로우하거나 저의 Website을 방문해 주십시오.

    좋은 웹페이지 즐겨찾기