[React] part.1 리액트 기초 - (3)

은채·2022년 9월 15일
0

React

목록 보기
3/5
post-thumbnail

13 컴포넌트 상태 다루기

컴포넌트

  • DOM : 논리 트리

  • 컴포넌트 : 엘리먼트의 집합

  • 엘리먼트 : 요소

  • useState가 바로 상태값을 관리해주는 react의 훅이다.
  • useState() 안에 들어있는 값이 초기 값
  • 이 안에는 문자도, 배열도, 불린 값도 넣을 수 있다
  • const [우리가 관리해야 할 state 상태 , 업데이트 하는 함수]

14 컴포넌트 사이드 이펙트 다루기

  • use~~로 시작하는 것들이 react의 훅이다.

사이드 이펙트?

  • 부작용
  • 의도하지 않은 효과 vs 부수 효과(변경, 효과가 일어날 때 그 효과를 다른 곳에도 전파하기 위함)

  • input에 쓴 내용을 남겨놓고 싶다면? => 로컬스토리지, 세션스토리지, 쿠키 등의 브라우저 저장 공간을 활용하자

  • onChange에 들어갈 함수에 localStorage 에 저장하는 함수를 써준다. setItem()

  • 다시 접속했을 때도 남아있게 하고 싶다면, keyword state의 초기값을 로컬스토리지에서 받아오고, input의 값으로 해볼까?

문제점 1

  • 하지만, 로컬스토리지에서 값을 읽어오면서 데이터가 크거나, 길면 딜레이가 생겨 문제가 생길 수도 있다.
    그럴 때, useState에는 함수로 값을 넣어줄 수 있다. 초기값을 리턴하는 함수를 사용해서 처음 값을 읽어오는 시간이 길더라도, 함수가 실행되면 값을 받아올 수 있게하자. => lazy initialize

  • render 보다 늦게 initialize가 찍힌다.

문제점 2

  • 어떤 동작을 하던지 계속해서 render 중
  • keyword가 바뀌었을 때만, 발생하는 사이드 이펙트로 로컬스토리지에 keyword가 저장되게 하자

  • useEffect 에서 두 번째 인자(dependency array)로 빈 배열을 두면 최초 렌더 시, 한 번만 실행
  • keyword가 바뀔 때마다 실행 되게 하려면, keyword state를 넣어준다.
  • 의존성 배열을 작성하지 않으면, 모든 변화에 반응하게 된다

15 커스텀 훅 만들기

  • keyword, typing, result가 바뀔 때 마다 로컬스토리지에 저장하고 싶다고하면 -> useEffect를 3번??? (비효율)

  • 반복되는 부분은 => 함수화

  • useState/useEffect가 반복되는 부분은 => use 커스텀 훅

  • state 값을 로컬스토리지에 저장하는 커스텀 훅을 만들어보자
  • 처음 만들었던 state와 로컬스토리지에서 값을 받아오는 초기값셋팅
  • 훅을 실행하면, useEffect도 state가 변할 때 실행하여 로컬스토리지에 저장하게 한다
  • 이 훅은 결과적으로 [state, setState] 를 반환하게 된다.

  • 우리가 사용할 state와 useState 대신 커스텀 훅을 쓰고, 인수로 state 이름을 보내준다
  • typing의 경우 타입이 boolean 이었기 때문에, 두 번째 인수로 보내주고 다른 것들은 기본값이 "" 일 수 있게 한다

application 확인

  • 아무것도 안 썼을 때

  • 작성 중일 때

  • click 했을 때

16 hook flow 이해하기

hook flow

  • 훅의 호출 타이밍
  • useState에 setState 시 prev(이전 동작)을 주입할 수 있음
 const rootElement = document.getElementById("root");

      const App = () => {
        console.log("App render start");
        const [show, setShow] = React.useState(() => {
          console.log("App useState");
          return false;
        });

        React.useEffect(() => {
          console.log("의존성 배열 없음");
        });

        React.useEffect(() => {
          console.log("의존성 빈배열");
        }, []);

        React.useEffect(() => {
          console.log("의존성 배열에 show");
        }, [show]);

        const handelClick = () => {
          setShow((prev) => !prev);
        };
        
      console.log("App render end"); // 여기!!

        return (
          <>
            <button onClick={handelClick}>search</button>
            {show ? (
              <>
                <input />
                <p></p>
              </>
            ) : null}
          </>
        );
      };
      
      console.log("App render end"); // 여기 아님!! 틀렸음
      ReactDOM.render(<App />, rootElement);

  • 최초 렌더링
    - ⚠️ 가장 바깥의 end ?? ====> 나는 왜 end가 먼저 render 되는거지???

    => 콘솔 위치를 ㅋㅋㅋ DOM이 그려지기 전에 했으니까!
    retrun 이전에 console.log를 해주자

    • 상단부터 순서대로 render -> useState -> end -> 이후에 useEffect

  • search 버튼 클릭했을 때
    1) 렌더
    2) 항상 실행되는 의존성 배열없는 useEffect / show가 변했을 때 실행되는 useEffect

17 hookflow 이해하기


  • Child 를 만들고, 기존 input/p 위치에 Child 컴포넌트를 넣어준다.
  • 최초 렌더링 시 console 순서는 처음과 같다.

  • show가 true 되었을 때는 app render/end -> Child render / end -> useEffect 확인

  • Child 안에서도 useState를 만들어서 사용해보자.
  • input의 value가 바뀔 때마다 state도 바뀔 것

  • show = true

  • Child가 나타나면서, App -> Child render/useState/end -> App에 있는 useEffect 실행

  • text가 바뀔 때는 Child 내부의 render가 반복된다. App은 바뀌지 않음.

  • Child 안의 useEffect도 확인해보자

  • 부모 (App) -> 자식 (Child) -> 자식의 useEffect -> 부모의 useEffect (최초 렌더링이 아니어서 빈배열은 작동하지 않음)

clean up


  • App, Child 에 있는 useEffect 들에 모두 return 을 해주어 clean up을 해보자
  • return을 하면서 다른 함수를 호출하면, 다시 동작할 때 이전의 사이드 이펙트를 지우고 다시 생성하는 것?

  • App에 있던 useEffect 들이 cleanup하는 것이 Child보다 먼저 실행되었따.

  • input 작성하면
  • render -> cleanup -> useEffect

  • show = false
  • Child 컴포넌트가 아예 제거 되는 상황인데, cleanup 함수가 모두 실행되었다.
  • [] useEffect도 clean up 은 실행되었다는 점
profile
반반무마니

0개의 댓글