강의, 책/[React] ReactJS로 영화 웹 서비스 만들기

#4. Props

hye3193 2024. 2. 16. 13:04

Props

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

function SaveBtn() {
    return <button>Save Changes</button>;
}
function ConfirmBtn() {
    return <button>Confirm</button>;
}
function App() {
    return (
        <div>
            <SaveBtn />
            <ConfirmBtn />
        </div>
    );
}

기존의 방식대로라면 버튼을 여러 개 만들 때, 각각 컴포넌트로 만들어주어서 렌더링한다

하지만 각각의 버튼에 공통된 속성들(ex. style)이 들어간다고 가정한다면, 하나의 수정사항이 생길 때마다 모든 버튼 컴포넌트를 수정해야 하는 문제가 생긴다

 

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

function App() {
    return (
        <div>
            <Btn text="Save Changes"/>
            <Btn text="Confirm"/>
        </div>
    );
}

직접 생성한 컴포넌트에 인자를 넣게 되면, 해당 함수에 props가 오브젝트의 형태로 아래와 같이 전달된다

{text: "Save Changes"}
{prop1: "Save Changes", prop2: 123, prop3: "test"}

여러개 전달할 경우 두번째 줄 코드처럼 전달되며, 함수에서 props를 받을 때는 인자 하나만 선언해주면 된다(인자를 여러 개 써도 오브젝트 형태로 딱 하나만 전달되기 때문)

 

따라서 전달받은 인자를 사용할 위치에서 props.{인자명} 을 사용해 주면 된다(오브젝트에서 key를 이용해 value값 받아오는 것)

 

그러나 여기서 좀 더 간편하고 기억하기 쉽게 인자를 받아서 사용하기 위해

function Btn({ text }) {
    return (
        <button>
            {text}
        </button>;
}

function App() {
    return (
        <div>
            <Btn text="Save Changes"/>
            <Btn text="Confirm"/>
        </div>
    );
}

함수에서 인자를 props라는 이름으로 받는 대신, 위와 같이 선언해 준다(오브젝트에서 프로퍼티를 꺼내두는 형태)

그러면 props.text 대신 그냥 바로 text라는 이름의 변수를 사용할 수 있게 된다

* 단, 오브젝트에서 프로퍼티를 꺼낼 때에는 반드시 전달받은 key 값과 동일한 이름으로 꺼내야 한다

* { text = "null" } 이런 식으로 인자에 디폴트값을 줄 수도 있다

 

여기서 커스텀 컴포넌트에서 전달하는 인자는 말 그대로 인자일뿐이다 onClick={function}과 같은 인자를 커스텀 컴포넌트에서 전달할 수도 있으나, 이는 이벤트 리스너의 역할을 하는 것이 아님!

function Btn({ text, onClick }) {
    return (
        <button>
            onClick={onClick}
            {text}
        </button>;
}

function App() {
    return (
        <div>
            <Btn text="Save Changes" onClick={함수명}/>
            <Btn text="Confirm"/>
        </div>
    );
}

커스텀 컴포넌트를 통해 이벤트 리스너를 만들고 싶다면 위와 같이 코드를 작성해주어야 한다

이벤트 리스너는 반드시 실제 HTML 컴포넌트 안에서 선언할 것

 

React Memo

이때 함수를 통해 부모 컴포넌트의 상태를 변경시킬 경우, 해당 컴포넌트가 리렌더링 된다(자식 컴포넌트들까지도)

하지만 아무 변화가 없는 자식 컴포넌트까지 리렌더링해 줄 필요는 없기 때문에, react memo를 이용할 수 있다

function Btn({ text }) {
    return (
        <button>
            {text}
        </button>;
}
const MemorizedBtn = React.memo(Btn);
function App() {
    return (
        <div>
            <MemorizedBtn text="Save Changes"/>
            <MemorizedBtn text="Confirm"/>
        </div>
    );
}

위와 같이 React.memo를 이용하면, 컴포넌트의 props가 변경되지 않는 한 리렌더링 할 필요가 없다고 전달해주는 것

 

Props Types

커스텀 컴포넌트를 통해 인자를 전달할 때, 인자의 타입을 제대로 숙지하지 못하고 엉뚱한 타입의 인자를 전달할 수도 있다

이를 방지하기 위해 PropTypes 패키지를 사용할 수 있다

function Btn({ text, fontSize }) {
    return (
        <button
            style={{
                fontSize={fontSize}
            }}
        >
            {text}
        </button>;
}
Btn.propTypes = {
    text: PropTypes.string.isRequired,
    fontSize: PropTypes.number
};
function App() {
    return (
        <div>
            <Btn text="Save Changes" fontSize=14/>
            <Btn text="Confirm" fontSize=16/>
        </div>
    );
}

* 뒤에 .isRequired를 붙여서 필수로 전달해야 하는 인자로 선언해줄 수도 있다

'강의, 책 > [React] ReactJS로 영화 웹 서비스 만들기' 카테고리의 다른 글

#6. Effects  (0) 2024.02.17
#3. State  (0) 2024.02.15
#2. The Basics of React  (0) 2024.02.15