본문 바로가기
WEB Frontend/📌노마드코더강좌

ReactJS로 영화 웹 서비스 만들기 #2 - State & Props

by IMSfromSeoul 2022. 5. 10.

State

state

 

 

이 코드에서 시작을 해보자.

코드는 간단하다. button을 누르면 counter += 1 증가되는 코드이다.

 

그런데 기대와는 다르게 click을 눌러도 counter가 증가하지 않는다.

그런데 console에 counter 값을 찍어보면 증가한 것을 볼 수 있다.

이는 현재코드에서 렌더링을 딱 1번만 하기 때문이다.

 

ReactDOM.render(<Container/>,root)

 

그렇다면 다음과 같이 counter를 증가시키는 함수 안에 ReactDOM.render 코드를 넣어서 렌더링을 그때 마다 해주면 되지 않을까?

맞다.

 

 

위와 같이 함수 안에 ReactDOM.render 함수를 넣어주니 원했던 대로 동작한다.

그러나 이는 언뜻 생각해봐도 좋은 방법이 아니다.

매 함수마다 render 함수를 호출해야 한다.

더 좋은 방법을 알아보자.

React의 강력한 점

button을 누르면, 바뀐 부분만 찾아서 update가 된다.

console > elements 의 코드를 보면 숫자 부문만 업데이트가 일어나는 것을 볼 수 있다.

즉, 매번 새로운 Component를 생성하지 않는다.

React.useState - setState

처음에만 rendering을 하고, 그 뒤부터는 바뀐 부분만 re-rendering을 하는 식으로 진행을 하려고 한다.

일단 useState에 대해서 알아보자.

 

 

useState를 선언하면 배열의 첫번째 값은 data, 두번째 값은 data를 바꿀 수 있는 함수(modifier)가 들어간다.

 

const data = React.useState(20)

 

만약 위와 같이 선언하면 

위와 같이 값이 들어감을 확인할 수 있다.

setState의 필요성

 

 

ReactDOM.useState 함수의 2번째 배열 값은 modifier이다.

위 코드처럼 해당 함수에 인자를 넘겨주면 해당 값으로 data의 값을 update해준다.

그리고 알아서 re-redering을 해준다.

 

React는 데이터가 바뀔 때마다 컴포넌트를 re-rendering해주고 UI를 refersh 해준다.

state가 바뀌면 re-rendering이 일어난다.

 

 

위처럼 함수에 console.log를 찍어보자.

그렇다면 위처럼 button을 클릭할 때마다 해당 console.log가 호출되는 것을 볼 수 있다.

State Function

 

 

setCounter( count + 1) 식으로 넣으면 값이 원하지 않게 바뀌는 경우가 생긴다.

그렇기 때문에 현재 값을 기준으로 바뀔 수 있도록 위와 같이 생성해주자.

Input & State

  • 분 -> 시로 변환하는 코드를 작성해보자.

"HTML식" 으로 작성하면 아래와 같이 작성할 수 있다.

 

 

 JSX에서는 class -> className, for -> htmlFor 등으로 바꿔줘야 한다.

input 값 받아오기

 

 

React는 event를 최적화 시켜서 최적화 된 가짜 event객체를 발생시킨다.

event.target.value를 보면 input에 값을 넣어줬던 data가 있는 것을 볼 수 있다.

해당 값을 setMinutes에 넣어주면 input -> minutes로 값 주입이 완료된다.

Value

 

 

value를 지정해놓으면 기존 minutes의 값을 그대로 가져오면서 rendering할 수 있다.

보통 위처럼 value, onChange 둘다 사용한다.

( value, event 둘다 사용 )

만약 event(onChange)를 달아주지 않는다면 value가 고정이 돼서 해당 input값을 수정해줄 수 없다.

분 -> 시 변환 완성

 

 

시 -> 분 변환하기

  • 분에서 시를 변환하는 것 뿐 아니라, 시에서 분을 변환하는 것도 해보자.
  • 분을 입력할 때는 시의 input이 disabled돼야 하고, 시를 입력할 때는 분의 input이 disabled돼야 한다.

완성 코드

 

 

  • 실수
    • button에서 onChange가 아니라 onClick을 해줘야 한다.
    • 익명 함수에서 setFlipped ( (cur) => !cur ) 을 해주던가, 대괄호( { } ) 을 넣어줄 거면 return 문을 넣어주어야 한다.

결과

컴포턴트 나눠보기

 

 

위처럼 select option에 따라 다른 컴포넌트를 표시하게 할 수 있다.

Props

props

🔖)props는 전달받는 properties의 준말이다.

 

부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법이다.

컴포넌트는 JSX를 반환하는 그냥 일반적인 함수일 뿐이다.

문제상황

다음과 같은 2개의 버튼을 갖는 상황이 있다고 해보자.

두 개의 버튼은 같은 스타일을 공유하고, 버튼안에 들어가는 텍스트만 다르지만 아래와 같이 다르게 선언해야 한다.

 

 

위 상황에서 Props를 사용하면 하나의 Btn컴포넌트를 재활용해서 사용할 수 있게 된다.

아래는 그 코드이다.

Component 재활용

 

 

컴포넌트는 함수다.

<Btn parameter = "안녕하세요">

 

위 코드는 사실 아래와 동치라고 볼 수 있다.

 

Btn({parameter: "안녕하세요"})

Props 최적화

위 코드에서 props.parameter로 값을 꺼냈는데, 굳이 이렇게 하지 않고

 

 

 

 위와 같이 해당 변수를 바로 꺼내서 사용할 수 있다.

Props 인자 여러개

 

 

당연하게도, 아래와 같이 여러 변수를 받을 수 있다.

React Memo

함수를 props로 전달

 

 

위와 같이 함수로 props를 전달할 수 있다.

위 코드는 아래와 같이 버튼을 누르면 기본값 -> 바뀐값으로 변하는 코드다.

App 부분의 state를 중심으로 보면 금방 이해할 수 있다.

이 때, 처음 함수가 렌더링이 되면 function Btn 윗부분에 선언해놓은 console.log("rendering") 때문에 redering이 2번 console에 찍히게 된다.

그리고 나서 버튼을 클리하면 다시 rederning이 2번 찍히게 된다.

이는 바뀌지 않는 나머지 Btn도 모두 호출된다는 뜻이다.

만약 Btn 컴포넌트 객체가 1000개 라면, 1개 바뀌는 것 때문에 999번이 다시 렌더링이 된다.

이는 상당히 비효율적일 수 있다.

그래서 React.memo를 통해 위 문제를 해결할 수 있다.

 

 

React.memo를 사용하면 바뀐 컴포넌트만 호출이 된다.

( App 바깥에 전역으로 선언해야 한다 )

Props type 지정

javascript는 type checking을 하지 않기 때문에 잘못된 타입을 전달할 수 있다.

이 때, prop-types 라이브러리를 통해 type checking을 할 수 있다.

 

<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>

 

위의 cdn을 추가해주자.

 

Btn.propTypes = {
    parameter: PropTypes.string,
    setValue: PropTypes.number
}

 

위처럼 propTypes를 지정해줌으로써 해당 컴포넌트의 type을 검사할 수 있다.

 

 

댓글