framework/react

2. State

wooweee 2023. 6. 6. 01:28
728x90

1. State 이해하기  

  • state: data가 저장되는 곳 -> 내용 추가
  • react element = function = react component

 

  • state 2가지 방식
    1. old 방법 -> 원리 파악용
    2. best 방법 -> old 방법으로 원리 파악 후, 더 편리한 방법으로, 실제 사용하는 방법

 

1.1. old 방법

  • {} : 동적 작업 내용을 넣는다.
    1. 변수
    2. function
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- body 끝 -->

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    
    <!-- inner text 할 필요없이 {}에 변수를 넣으면 적용이 된다.-->
    let counter = 0;
    const root = document.getElementById("root");
    const Container = () => (
      <div>
        <h3>Total clicks: 0 {counter} </h3>
        <button>Click me</button>
      </div>
    );

    ReactDOM.render(<Container />, root);
  </script>
</html>

 

  • ReactDOM 작동원리
    • 초기에 rendering 된 후, rendering을 직접 지정하지 않으면 rendering이 되지 않는다.

    • ReactDOM.render()만 초기 rendering시 render되므로 component내부에 재 render되도록 해당 method 따로 빼주고 rerender되도록 한다.

 

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- body 끝 -->

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");

    let counter = 0;

    function countUp() {
      counter += 1;
      render();
    }

    function render() {
      ReactDOM.render(<Container />, root);
    }

    // onClick에 React의 문법 넣어줌
    const Container = () => (
      <div>
        <!-- inner text 할 필요없이 {}에 변수를 넣으면 적용이 된다.-->
        <h3>Total clicks: {counter} </h3>
        <!-- OnClick에 function을 사용-->
        <button onClick={countUp}>Click me</button>
      </div>
    );

    render(); <!-- 초기 render 수행-->
  </script>
</html>

 

1.2. react와 vanilla js의 차이점 - 아주아주 중요

  • vanilla js의 경우에는 component를 통채로 업데이트한다.
  • 반면 react의 경우에는 변경되는 point만 변경을 수행한다.
    -> 내부적으로 볼때, 얘 또한 rerender 되는 것 같지만, react는 변경된 부분만 바꾼다.

 

 

2. new 방식

  • react 내부에 데이터를 보관하고 자동으로 리렌더를 하는 방식을 보여줄 것이다.
  • let countNum을 하는 것이 아니라 React의 role을 따르는 방식을 이용해볼 것이다.

 

  • 처음 setting
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- body 끝 -->

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      return (
        <div>
          <h3> Total clicks: 0 </h3>
          <button> Click me </button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

 

  • React.useState(); 배열 형식을 반환한다. [undefined, f ] -> 뭔가를 제공해줄 것이다.
    • undefined: 넣을 data
    • f : 동적으로 data를  변경해주는 함수
  • 이전의 2가지 code를 간략화 시켜준다.

 

 

해당 array를 사용하는 편법 비슷한 방법

const food = ['tomato', 'potato']

  const [myFavFood, mySecondFavFood] = food;

  위의 코드는 food[0], food[1]과 동일한 기능을 한다.

 

 

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- body 끝 -->

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [counter, modifier] = React.useState(); // 1st params: data, 2nd params: function which change data
      // const counter = data[0];
      // const modifier = data[1];

      return (
        <div>
          <h3> Total clicks: {counter} </h3>
          <button> Click me </button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

 

 

  • 직접 rerender하는 것이 아니랑 react.js를 통해서 자동으로 값 update 및 rerender하는 것 을 보여줌
  • modifier()

 

  • 참고_화살표 함수
    • () => () // 반환 값이 존재하지 않는 경우 사용
    • () => {return} // 반환 값이 존재하는 경우 사용
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <!-- body 끝 -->

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      const [counter, setCounter] = React.useState(0); // 1st params: data, 2nd params: function which change data
      // const counter = data[0];
      // const modifier = data[1];

      const onClick = () => {
        // modifier() : 값을 update하고 rerender해주는 함수
        // 해당 함수는 1. counter의 값을 변경하고  2. ReactDOM.render()까지 내부적으로 수행
        setCounter(counter + 1); // useState에서 부터 받아온 값들을 onClick이라는 function에 넣어준다.
      };

      return (
        <div>
          <h3> Total clicks: {counter} </h3>
          <button onClick={onClick}> Click me </button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

 

 

오타 : clicks: 0이 아니라 clicks: {counter}

 

3. 중간 정리

  • old
    • createElement()
    • ReactDOM.render()

 

문법 측면

  • babel
    • Tag()
    • ReactDOM.render()

 

logic 측면

  • State()
    • useState() // 자동 reRender
      • state data
      • state function
    • Tag()
    • ReactDOM.render()

 

4. state function 사용 방법 

  1. setCounter() 의 params에 직접 넣기
    string, Number, ...등 type 상관 없다.

  2. setCounter() 의 params에 넣기
    • counter +1
      이렇게 하면 잡기 힘든 버그가 발생할 가능성이 생긴다.
      - counter라는 state data의 현재값이 적용되지 않는 경우가 존재할 가능성이 있다.

    • (current)=> current+1
      람다식으로 작성시, 현재값이 무조건 적용이 되기 때문에 안전하다.