React 기초 정리 4편

정인아·2022년 6월 15일
1

React

목록 보기
4/4

지난 번 정리편에서 state의 기초와 EventHandler에 대해서 다뤘습니다.
이번 정리편에서는 state에 대해서 조금 더 자세히 다뤄보겠습니다.

input과 state

제가 회사에서 처음 맡았던 프로젝트는 이커머스 프로젝트였습니다.
결제기능이 포함된 사이트였죠. 결제기능이 있다는 말은 결제를 위한 페이지가 존재하고 이 페이지에서 중요하고 많은 데이터를 다뤄야합니다.

예를 들면,

  • 주문자 정보(이름, 주소, 전화번호 등등)
  • 배송지 정보(우편번호, 주소, 상세주소 등등)
  • 구매하려는 상품정보(메인 상품, 옵션, 수량 등등)
  • 회원이라면 마일리지 및 쿠폰

여기서 배송지 정보를 살펴볼까요.

회원이라면 아마 회원가입시 주소를 입력했을겁니다.
그런데 회원이 꼭 기입했던 주소로만 배송하라는 법은 없죠.

즉, 배송지를 직접 입력하여 구매할 수 있습니다.

여기서 직접 입력에 대해서 생각해보죠.

제목에서 어필했듯이 input태그를 사용할 겁니다.
그러면 한번 작성 해보겠습니다.

웹상에서도 아무 텍스트나 작성해보겠습니다.

여기까지는 아무 문제없죠.
이제 저 텍스트를 변수에 저장해야합니다.
바닐자 자바스크립트 같은 경우, 명령형 방식이라고 말씀 드린적이 있습니다.
그래서 input의 value값을 받아와서 저장할겁니다.

	const input = document.querySelector("input");
    const value = input.value;

위와 같이 말이죠.

하지만 리액트에서는 값의 변화를 감지하여 해당 컴포넌트를 리렌더링해야하기 때문에 useState를 사용해야하죠.

지금까지 저희가 배웠던 걸 적용해보겠습니다.

음...

적어보려하니 막막합니다. 클릭 이벤트야 addEenvtListener대신에 onClick사용한다고 했고, input를 잡아오려하니 리액트에서는 querySelector를 사용하지 못합니다.

그래서 input태그에 props로 value를 넣어보려 합니다.

자, 이제 웹상에서 input에 텍스트를 적어보겠습니다.
시도해보신 분들은 알시겠지만, 웹상에서 아무 일도 일어나지 않습니다.

왜그럴까요?

text라는 변수를 input에 value로 넣었지만, text라는 useState 훅으로 가져온 변수는 setText를 통해서만 값이 바뀐다고 말씀드렸습니다.
즉, input 박스에 아무리 타자를 치더라도 text라는 변수는 ""값으로 유지되기에 input의 value가 계속 "" 입니다.

그러면 입력한 텍스트를 어떻게 text라는 변수에 대입할 수 있을까요?
바닐라 자바스크립트에서 change라는 이벤트를 사용 해보셨을겁니다. 이와 비슷하게 onChange라는 props를 넘겨줍니다.

onClick과 비슷하게 on으로 시작하는걸 보니 Event라는걸 눈치 채셨을겁니다.
그렇다면 저희는 콜백함수를 props로 넘겨줘야하죠.

자, 이제 웹상에서 타자를 쳐보고 콘솔을 확인 해볼게요.

이렇게 콘솔에 찍힌다는건 함수가 분명 실행됩니다.
자 이제 setText를 적용해보겠습니다.
바닐자 자바스크립트에서 addEventListener를 사용했을때, 콜백함수는 event라는 변수를 넘겨주죠. 이걸 활용해야합니다.

이제 웹상에서 타자를 치게되면 입력되는걸 볼 수있죠.
onChange props 덕분에 setText에 input에 입력된 value값으로 text를 변경시키고 setText가 호출되었으니, 컴포넌트가 리렌더링되며 바뀐 text가 적용되는겁니다.

개념이 헷갈릴수 있지만, 한번 이해하시게되면 편하게 사용 하실겁니다.

여기서 주의할 점은

텍스트를 입력할때마다 리렌더링 되기때문에 컴포넌트 분할에 신경을 많이 써야합니다.

한 컴포넌트에 input과 여러가지 컴포넌트가 있다면, input의 onChange때문에 다른 컴포넌트에서는 불필요한 리렌더링이 발생합니다.
최적화에 적절하지 않습니다.

onChange의 경우, 함수가 한줄로 끝난다면 굳이 함수를 정의하지 말고 익명 함수로 바로 처리 할 수도 있습니다.

<input value={text} onChange={(e) => setText(e.target.value)} />

이렇게 말이죠.

props와 state

이전 기초 정리에서 props에 대한 설명을 드린적이 있습니다.
props는 부모의 컴포넌트가 감싸고 있는 자식 컴포넌트에게 전달해주는 data를 props라고 합니다.
그리고 자식이 부모에게 전달할 수 없다고 말씀드렸습니다.

하지만, 자식 컴포넌트에서 꼭 부모 컴포넌트로 데이터를 끌어와야 한다면 어떤 방식을 써야 할까요?

답을 먼저 알려드리자면, props 함수를 이용합니다.
설명보다 코드를 참고하면 이해가 빠를꺼 같습니다.

onGetData라는 함수의 파라미터를 받아와서 콘솔에 찍히게 정의했습니다.
그리고 TItle이라는 컴포넌트에 props로 넘겨줬죠.

TItle이라는 컴포넌트에서는 해당 함수에 Title에서 선언한 useState를 파라미터로 넣어 실행시켰습니다.
콘솔을 확인 해볼까요?

이러한 방식처럼 자식의 data를 부모 컴포넌트로 끌어 올릴수 있습니다.
형제 컴포넌트끼리의 data도 부모를 통한다면 문제 없이 가능하죠.

이미 1편은 정리되있는 recoil과 나중에 정리할 redux와 같은
전역 상태관리 라이브러리를 사용하게 된다면, 이런 data의 이동이 훨씬 자유로워 질겁니다.
react와 전역상태 라이브러리는 필수라고 할만큼 서로 짝을 지어 다니니 하나의 라이브러리는 꼭 제대로 공부 하시길 추천 드립니다.

Stateless 컴포넌트 / Stateful 컴포넌트

컴포넌트의 장점 중 기능단위로 컴포넌트를 쪼갤수 있다라고 말씀드린적 있습니다.
컴포넌트의 분할은 무조건 작게 쪼개는게 좋은게 아닙니다.
리렌덩이 일어나는 컴포넌트와 리렌덩링이 필요없는 컴포넌트로 나누는게 제일 좋습니다.

예를 들어 보자면,

컴포넌트를 Title과 Input 컴포넌트로 나눴습니다.
자세히 보시면 Input 컴포넌트에서는 useState를 호출하며 setTitle이 호출될때 마다 해당 컴포넌트를 리렌더링 할 것입니다.

그러면 Title 컴포넌트는 어떨까요?
props를 받아와 렌더링후, 리렌더링을 하기위한 로직이 없습니다.
때문에 해당 컴포넌트는 title이라는 props만 바뀌지 않는다면, 리렌더링되지 않을 것이며, 이를 dumb 컴포넌트 라고 합니다.

Title의 props는 string으로 고정이지만 state가 props로 넘겨온다면 해당 state가 변화할때마다 컴포넌트는 리렌더링합니다. 이 때, props로 받은 data가 변화하지 않는다면 리렌더링을 막아주는 React.memo를 사용해야합니다.
이에 관련된 내용은 다른편에서 다시 설명드리겠습니다.

이번 편은 여기까지 이고, state에 관한 정리는 끝났습니다.
긴 글 지루하셨을텐데 봐주셔서 감사합니다.
다음 편에서는 조건부 렌더링에 대한 이야기로 돌아오겠습니다.!!

profile
프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2023년 4월 17일

대박이네요... 도움이 많이 되었습니다!!!!!

답글 달기
comment-user-thumbnail
2023년 4월 19일

혹시 5편은 없나요???

답글 달기