props란 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법이다.
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>
);
}
부모 컴포넌트인 App 컴포넌트에서 넣어준 속성들을 내가 만든 Btn 컴포넌트의 첫 번째 인자로 넣어주는데 이것이 바로 props이다. 리액트는 자동으로 이 모든 properties들을 오브젝트, 즉 props 안으로 집어 넣는다.
위에서 같은 Btn 컴포넌트를 사용하지만, 이 버튼들은 App 컴포넌트에 의해 설정되고 있다. 이렇게 하나의 버튼을 만들어서 props를 이용해 버튼의 스타일을 관리해 재사용할 수 있다.
function Btn({ text, changeValue }) {
console.log(text, 'was rendered');
return (
<button
onClick={changeValue}
style={{
backgroundColor: 'tomato',
color: 'white',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{text}
</button>
);
}
중요한 것은 이렇게 props를 부모 컴포넌트로부터 내려받았을 때 이를 직접 return문 안에 넣어줘야 한다는 것이다. changeValue라는 함수를 전달받았으니 이 props의 이름을 버튼의 event handler로 직접 넣어줘야 한다.
React.memo()
위 예시에서 부모의 상태를 바꾸는 changeValue 함수는 자식 컴포넌트가 실행시킨다. 부모 컴포넌트의 state가 변경될 때 return 문 안 모든 요소가 리렌더링되는데 props가 변경되지 않는 두 번째 버튼은 리렌더링 할 이유가 없다.
이때 React Memo를 쓸 수 있다. 이는 리액트에게 만약 props가 변경되지 않는다면 해당 컴포넌트는 리렌더링될 필요가 없다고 말해주는 기능으로 어플리케이션을 최적화할 수 있는 방법 중 하나이다.
const MemorizedBtn = React.memo(Btn);
function App() {
const [value, setValue] = React.useState('Save Changes');
const changeValue = () => setValue('Revert Changes');
return (
<div>
<MemorizedBtn text={value} changeValue={changeValue} />
<MemorizedBtn text="Continue" />
</div>
);
}
React.memo()를 사용하여 래핑된 컴포넌트는 props 변화를 감지하여 컴포넌트를 호출할지 말지를 결정한다.