본문 바로가기
프로그래밍/React

React Props,State

by slowin 2024. 7. 29.

Props

React에서 설명하는 Props

“props” (props는 속성을 나타내는 데이터입니다) 객체 인자를 받은 후 React 엘리먼트를 반환하므로 유효한 React 컴포넌트입니다. 이러한 컴포넌트는 JavaScript 함수이기 때문에 말 그대로 “함수 컴포넌트”라고 호칭합니다.

리액트에서 props를 속성을 나타내는 데이터라고 표현한다.

Props는 read-only 이다.

    • Props를 전달해보자

  • Props를 수정해보자.
      • 해당 코드를 실행하면 멋지게

분명 let name = "John"; 수정 가능한 let으로 선언 했지만, 자식 컴포넌트(객체)에서 수정접근시 read only라 수정할 수 없다는 에러가 발생한다.

😒 왜 그럴까?

이유는 ReactElement 를 생성할때 props와 element 를 freeze해버리기 때문이다.

개인적으론, 무분별한 getter , setter를 지양하는 입장에서 너무나도 당연해 보인다.

부모 컴포넌트(객체)가 전달한 속성을 자식 컴포넌트(객체)가 수정하는 것은 불안전한 코드이다.

그렇다면 리액트는 왜 수정불가로 하는걸까?

변경의 주체는 오직 하나. (Immutable)

장점

  • 동작이 예측가능하다.
  • 변경의 주체가 하나로 모이게 된다면, 해당 객체에서만 변경을 감지하면 되기 때문에 변경을 감지하기 용이하다.

변경을 어디서든 허용했을때

  • 데이터가 어디서든지 변경가능 하다면, 디버깅을 하거나 변경을 했을때 관찰해야하는 영역이 점차 늘어나기 때문에 예측가능하기 힘들어진다.
  • 리액트가 관리하고 있는데, 어딘가에서 변경가능하다면 리액트입장에서는 Props를 신뢰할수 없을 것이다.

순수함수 처럼 동작하도록 하라.

모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 합니다. (링크)

순수함수란?

  • 외부의 값을 변경하지 않고, 부수효과 없이 주어진 인자로 항상 같은 값을 리턴하는 함수

불순한 함수

  • 외부의 값을 수정하고 있다. 실무에서 수백줄의 코드가 하나의 파일로 되어있는 경우가 허다하다. 수백줄의 코드에서 값을 중구난방으로 수정하고 있는 코드를 수정해야 한다고 상상해보라. 그 코드를 수정했다한들 문제가 없을꺼라 확신 하기 힘들 것이다.

순수 함수

  • 자신의 영역 주어진 인자로 외부영향 없이 하나의 책임만 수행하고 리턴하자.

정리

  1. props는 read only이다.
    1. 불변성을 유지함으로써 최적화 호율, 변경감지 용이성 등의 장점을 가진다.
  2. props를 다룰때 순수함수 처럼 동작하도록 하라.

React State

수정 할 수 있는 상태

부모에게 전달받은 상태(Props)는 수정 할 수 없다.

자신이 만든 상태(State) 는 수정할 수 있다.

Props는 전달받는 상태(내가 만들지 않은 상태)이라고 한다면, State는 컴포넌트(객체)가 직접 만드는 상태라고 할 수 있다.

내가 만드는 상태니까 내가 수정가능하다.

사실은 수정이 아니라 새로운 객체를 만드는것이다.

상태를 변경해보자

예시코드

화면

“let 이름 변경” 버튼을 클릭하더라도 이름이 변경 되지 않을것이다.

😒 왜 그럴까?

왜냐하면, 리액트가 모르기 때문이다.

리액트가 알 수 있도록 이벤트에 등록해주는 Hook을 사용해야한다.

상태변화를 알려주는 useState를 사용하자.

useState를 사용하면 어떻게 변경을 감지해서 리렌더링 하는걸까?

  • useState Hook 함수를 실행하면 리액트 이벤트로 등록이 되기 때문이다.

리액트가 관리하는 dispatch 함수를 리턴받는다.

🤩 결국, useState가 반환하는 두번째 인자는 리액트가 등록한 event dispatch 함수이기 때문에 변경 감지시 렌더링 프로세스를 수행하는 것이다.

useState 변경 두가지 방식

값을 전달하는 방식

  • count 를 증가시켜보자.
const StateCounter = () => {
    const [count, setCount] = useState(0);

    return (
        Count: {count}
        <button> { setCount(count + 1) setCount(count + 1) setCount(count + 1) setCount(count + 1) }}>+1</button>
    )
}

+1 버튼을 클릭하면, count를 4번 증가시키는것 같지만 결과는 count가 0이 었다면 1의 결과를 반환한다.

dispatchSetState 호출을 디버깅하보면, 해당 호출 **시점**에 넘겨준 값을 업데이트 객체에 넣는 것을 알 수 있다.

함수 scope영역이 끝나기 전까지는 count는 업데이트 되지 않는 것이다.

() => {
    setCount(count + 1)
    setCount(count + 1)
    setCount(count + 1)
    setCount(count + 1)
}

결국 setCount(count + 1) 호출시점에 count 에 할당되어 있는 값을 동일하게 주는것이다.

함수를 전달하는 방식

함수 형태로 전달하자.

 {
    setCount((prevCount) => prevCount + 1)
    setCount((prevCount) => prevCount + 1)
    setCount((prevCount) => prevCount + 1)
    setCount((prevCount) => prevCount + 1)
}

callback 형태 인자를 전달할때의 결과값은 0 이 아니라 4로 변경되는것을 확인할 수 있다.

dispatchSetState 메소드를 분석해 보았을때, 콜백 형태의 함수를 전달하면, 리액트 메모리상에 있는 state를 접근해서 업데이트 하는듯하다.

정리

  • 컴포넌트(객체)에서 변하는 것을 State라고 한다.
    • 리턴 받은 Dispatch 함수로 State를 변경 할 수 있다.
    • State를 재할당 하는것이 아니다. 새로운 상태를 만들어서 다시 주는것이다.
  • 변경 감지를 위해서는 리액트가 알 수 있도록 Hook을 통해서 이벤트로 등록해줘야 한다.

참고

'프로그래밍 > React' 카테고리의 다른 글

Golang Slice(슬라이스) 동작원리와 사용법  (0) 2024.07.31
React Virtual DOM  (0) 2024.07.29
React Composition  (0) 2024.07.29
React Function and Class Components  (0) 2024.07.29