[React] State

J·2023년 5월 12일
0

React

목록 보기
5/25
post-thumbnail
post-custom-banner
  • State란?

    const [ value, setValue ] = useState( 초기값 )
    • 컴포넌트 내부에서 바뀔 수 있는 값.
    • state를 만들 때는 useState() 훅 사용.
    • state를 변경할 때는 setValue 사용.
  • useState + onClick Event

    import React, { useState } from "react";
    
    function App() {
      const [name, setName] = useState("길동이");
    
      function onClickHandler() {
        setName("누렁이");
      }
    
      return (
        <div>
          {name}
          <button onClick={onClickHandler}>버튼</button>
        </div>
      );
    }
    
    export default App;
  • useState + onChange Event
    import React, { useState } from "react";
    
    const App = () => {
      const [value, setValue] = useState("");
    
      const onChangeHandler = (event) => {
        const inputValue = event.target.value;
        setValue(inputValue);
      };
    
    	console.log(value) // value가 어떻게 변하는지 한번 콘솔로 볼까요?
    
      return (
        <div>
          <input type="text" onChange={onChangeHandler} value={value} />
        </div>
      );
    };
    
    export default App;
  • 불변성이란?
    • 메모리에 있는 값을 변경할 수 없는 것을 말함. JS 데이터 형태 중 원시 데이터는 불변성이 있고 원시 데이터가 아닌 객체, 배열, 함수 등은 불변성이 없음.
    • 만약 우리가 let number = 1 이라고 선언을 하면, 메모리에는 1 이라는 값이 저장됩니다. 그리고 number 라는 변수는 메모리에 있는 1을 참조하죠. 그리고 이어서 우리가 let secondNumber = 1 이라고 다른 변수를 선언을 했다고 가정해봅시다. 이때도 자바스크립트는 이미 메모리에 생성되어 있는 1이라는 값을 참조합니다. 즉, number와 secondNumber는 변수의 이름은 다르지만, 같은 메모리의 값을 바라보고 있는 것이죠. 그래서 우리가 콘솔에 number === secondNumber 를 하면 true가 보입니다. 하지만 원시데이터가 아닌 값(객체, 배열, 함수)는 이렇지 않아요. let obj_1 = {name: ‘kim’} 이라는 값을 선언하면 메모리에 obj_1이 저장이 됩니다. 그리고 이어서 let obj_2 = {name: ‘kim’} 이라고 같은 값을 선언하면 obj_2라는 메모리 공간에 새롭게 저장이 됩니다. 그래서 obj_1 === obj2false 가 되죠.
    • 다시 원시데이터로 돌아와서 만약에 기존에 1이던 number를 number = 2 라고 새로운 값을 할당하면 메모리에서는 어떻게 될까요? 원시 데이터는 불변성이 있습니다. 즉, 기존 메모리에 저장이 되어 있는 1이라는 값이 변하지 않고, 새로운 메모리 저장공간에 2가 생기고 number라는 값을 새로운 메모리 공간에 저장된 2를 참조하게 됩니다. 그래서 secondNumber를 콘솔에 찍으면 여전히 1이라고 콘솔에 보입니다. number와 secondNumber는 각각 다른 메모리 저장공간을 참조하고 있기 때문이죠. obj_1를 수정해봅시다. obj_1.name = ‘park’ 이라고 새로운 값을 할당하면 어떻게 될까요? 객체는 불변성이 없습니다. 그래서 기존 메모리 저장공간에 있는 {name: ‘kim’} 이라는 값이 {name : ‘park’} 으로 바뀌어 버립니다. 차이를 아시겠나요? 원시데이터는 수정을 했을 때 메모리에 저장된 값 자체는 바꿀 수 없고, 새로운 메모리 저장공간에 새로운 값을 저장합니다. 원시데이터가 아닌 데이터는 수정했을 때 기존에 저장되어 있던 메모리 저장공간의 값 자체를 바꿔버립니다.
  • 왜 리액트에서는 원시 데이터가 아닌 데이터의 불변성을 지켜주는 것이 중요한지?
    • 리액트에서는 화면을 리레더링 할지 말지 결정할 때 state의 변화를 확인합니다. state가 변했으면 리렌더링 하는 것이고, state가 변하지 않았으면 리렌더링을 하지 않죠. 그때, state가 변했는지 변하지 않았는지 확인하는 방법이 state의 변화 전, 후의 **메모리 주소를 비교합니다. 그래서 만약 리액트에서 원시데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지 않고, 직접 수정을 가하면 값은 바뀌지만 메모리주소는 변함이 없게 되는것이죠.** 그래서 즉, 개발자가 값은 바꿨지만 리액트는 state가 변했다고 인지하지 못하게 됩니다. 그래서 결국 마땅히 일어나야 할 리렌더링이 일어나지 않게되죠.
  • 리액트 불변성 지키기 예시
    import React, { useState } from "react";
    
    function App() {
      const [dogs, setDogs] = useState(["말티즈"]);
    
      function onClickHandler() {
    		// spread operator(전개 연산자)를 이용해서 dogs를 복사합니다. 
    	  // 그리고 나서 항목을 추가합니다.
        setDogs([...dogs, "시고르자브르종"]);
      }
    
      console.log(dogs);
      return (
        <div>
          <button onClick={onClickHandler}>버튼</button>
        </div>
      );
    }
    
    export default App;
  • 함수형 업데이트
    // 기존에 우리가 사용하던 방식
    setState(number + 1);
    
    // 함수형 업데이트 
    setState(() => {});
    
    // 현재 number의 값을 가져와서 그 값에 +1을 더하여 반환한 것 입니다.
    setState((currentNumber)=>{ return currentNumber + 1 });
    • useState 업데이트에는 2가지 방식이 있고, 각각 다르게 동작함.
    • 일반 업데이트 방식은 버튼을 클릭했을 때 n번의 명령을 내리면 리액트는 하나로 모아 최종 한 번만 실행함. 이를 batch 로 처리한다고 함.
    • ↔ 함수형 업데이트 방식은 동시에 n번 명령을 내리면 그 명령을 모아 순차적으로 각각 1번 씩 실행시킴.
profile
벨로그로 이사 중
post-custom-banner

0개의 댓글