본문 바로가기
FrontEnd/React

[ReactJS] Props - ReactJS 로 영화 웹 서비스 만들기 (4)

by 풍파 2021. 11. 26.

 

이번엔 props 를 이해하기 위해

버튼 컴포넌트를 이용한 실습을 해볼 것이다.

 

 


 

 

#4. Props

 

props

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

 

자식 컴포넌트의 첫 번째이자 유일한 인자 (argument) 이다.

text, boolean, function, ... 등 어떤 형태로든 보낼 수 있다.

 

 

Practice - (1) 여러 개의 버튼 만들기

function SaveBtn() {
    return (
        <button style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
        }}>Save Changes</button>
    )
}
function ConfirmBtn() {
    return (
        <button style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
        }}>Confirm</button>
    )
}
function App() {
    return (
        <div>
            <SaveBtn />
            <ConfirmBtn />
        </div>
    );
}
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);

 

SaveBtn 과 ConfirmBtn 컴포넌트 생성

 

-> 버튼을 만들 때마다 style 을 복사해서 사용해야 함 => 비효율적
어차피 버튼 글자만 다른건데... 하나로 만들자!!

 


 

Practice - (2) Props 전달

부모 컴포넌트의 Props 전달

<Btn text="Save Changes"/>
<Btn text="Continue"/>

 

전달할 property = 값 의 형태로 Props 전달

property 의 이름은 원하는대로 지어도 상관 없음     ex) text, tomato, ...

 

 

자식 컴포넌트가 Props 를 받아오는 방식 1

function Btn(props) {
    return (
        <button style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
        }}>{props.text}</button>
    )
}

 

props 라는 argument 를 받아서 props.text 형태로 사용

 

자식 컴포넌트가Props 를 받아오는 방식 2

function Btn({text}) {
    return (
        <button
            style={{
                backgroundColor: "tomato",
                color: "white",
                padding: "10px 20px",
                border: 0,
                borderRadius: 10,
        }}>{text}</button>
    )
}

 

props 는 오브젝트이기 때문에 가져올 property 의 이름을 { } 와 함께 바로 사용하기도 함

주의할 점, 보내는 property 이름받는 property 이름일치해야 한다.

 

보통은 2번째 방식을 많이 사용함

 

 

일부 Props 만 전달할 경우

<Btn text="Save Changes" index={1}/>
<Btn text="Continue"/>

 

만약 Continue 버튼이 index 를 전달하지 않았다면

=> Btn 컴포넌트는 undefined 를 받게 됨

 

이럴 경우를 대비해 default 값을 설정할 수 있다.

 

function Btn({text, fontSize = 14}) { ... }

 

 

style 에서의 Props 사용

function Btn({text, fontSize}) {
    return (
        <button
            style={{
                backgroundColor: "tomato",
                color: "white",
                padding: "10px 20px",
                border: 0,
                borderRadius: 10,
                fontSize: fontSize
        }}>{text}</button>
    )
}
function App() {
    return (
        <div>
            <Btn text="Save Changes" fontSize={20}/>
            <Btn text="Continue" fontSize={16}/>
        </div>
    );
}

 

props 는 style 에서도 사용 가능하다.

 

fontSize 를 받아와서 사용

 

fontSize: fontSize => 이름이 같기 때문에 fontSize 만 써도 O

 

function Btn({text, index}) {
    return (
        <button
            style={{
                backgroundColor: "tomato",
                color: "white",
                padding: "10px 20px",
                border: 0,
                borderRadius: 10,
                fontSize: index === 1 ? 20 : 16
        }}>{text}</button>
    )
}
function App() {
    return (
        <div>
            <Btn text="Save Changes" index={1}/>
            <Btn text="Continue" index={2}/>
        </div>
    );
}

 

style 에서 삼항 연산자를 이용해 적용할 수도 있다.

 


 

Practice - (3) Props 로 함수 전달

function Btn({text, changeValue}) {
    return (
        <button
            onClick={changeValue}
            style={{
                backgroundColor: "tomato",
                color: "white",
                padding: "10px 20px",
                border: 0,
                borderRadius: 10,
        }}>{text}</button>
    )
}
function App() {
    const [value, setValue] = React.useState("Save Changes")
    const changeValue = () => setValue("Revert Changes")
    return (
        <div>
            <Btn text={value} changeValue={changeValue}/>
            <Btn text="Continue"/>
        </div>
    );
}

 

Save Changes 버튼을 클릭하면 Revert Changes 버튼으로 바뀌도록 해보자.

 

App()

value 라는 state 를 이용해 버튼 상태 저장

changeValue 는 Revert Changes 로 value 를 바꾸는 함수

 

Btn 컴포넌트로 value 와 changeValue 를 넘겨준다.

 

Btn 컴포넌트

changeValue 함수를 받아와 버튼 onClick 에 적용

 

커스텀 컴포넌트에 전달하는 onClick 함수는 이벤트 리스너가 아니다.

HTML 요소에 넣어야 이벤트 리스너가 됨

=> button 태그를 위한 이벤트 리스너가 아닌 Btn 컴포넌트를 위한 props 일 뿐

 

 

결과

 


 

Prop-Types

만약, Props 로 넘기는 값에 실수를 할 경우 -> 문법 상의 오류는 없지만 구현 상의 오류 발생 가능

=> Prop-Types 를 이용하면 예방할 수 있다.

 

https://unpkg.com/prop-types@15.7.2/prop-types.js 추가

사용법

Btn.propTypes = {
    text: PropTypes.string,
    fontSize: PropTypes.number
}

 

예시

<Btn text="Continue" fontSize={"hi"}/>

 

fontSize 는 number 로 지정해뒀지만 문자열을 입력할 경우

 

=> 에러 발생까지는 아니지만 최소한의 경고문을 볼 수 있음

 

propTypes 가 적용 되지 않는 경우,
https://unpkg.com/react@17.0.2/umd/react.production.min.js 를 https://unpkg.com/react@17.0.2/umd/react.development.js 로 수정

 

- https://ko.reactjs.org/docs/typechecking-with-proptypes.html => propTypes 공식 문서

- required 를 이용하면 필수적으로 해당 property 가 존재하도록 지정 가능

- TypeScript 를 사용하면 필요 없는 기능이다.

 

 

참고) React Memo

- 기억할 필요는 없으며 이런 게 있다는 것만 알아두기...

 

부모 컴포넌트가 state 변경을 겪으면 모든 게 새로 그려진다.

(Save 버튼과 Continue 버튼이 같이 그려짐)

-> 추후 어플리케이션이 느려지는 원인이 될 수 있음

 

React Memo 는 props 가 변할 때만 re-render 하게 할 수 있다.

(Continue 는 그려지지 않음, 새로운 버튼만 그려짐)

 

function Btn({text, changeValue}) { ... }

const MemorizedBtn = React.memo(Btn);

function App() {
    ...
    return (
        <div>
            <MemorizedBtn text={value} changeValue={changeValue}/>
            <MemorizedBtn text="Continue"/>
        </div>
    );
}

 

 


 

 

여기까지 ReactJS 의 기본 지식을 배워보는 시간이었다.

 

다음 강의부터는 본격적으로 React 사용 시작!!

전문적인 방식으로 ReactJS 를 구현할 것이다.

 

 

댓글