이 글은 노마드 코더님의 React 강의를 학습한 내용을 기반으로 작성합니다.
props를 통해 전달할 수 있는 것들에 대해 자세히 알아본다.
기존 예제 코드에 onClick function을 추가해 App 컴포넌트에 있는 무언가의 state를 바꾸어본다.
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Changes");
return (
<div>
<Btn text="Save Changes" onClick={changeValue} />
<Btn text="Continue" />
</div>
);
}
여기서 중요한 점은 우리가 만든 커스텀 컴포넌트에 작성하는 onClick은 Btn 컴포넌트로 전달되는 property라는 것이다.
(실제 Event Listener가 아니다)
function Btn({ text }) {
return (
<button
onClick={changeValue}
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize: 16,
}}
>
{text}
</button>
);
}
위와 같이 HTML 요소 내부에 onClick을 삽입한다면 이것은 Event Listener에 해당한다.
주의!
property를 전달하고 사용할 때는 동일한 이름을 사용해야 한다.
또한, prop은 우리가 원하는 위치에 직접 사용해야 한다.
(React.js가 자동으로 사용해주지 않는다)
React.js의 기능을 더 알아본다.
<!DOCTYPE html>
<html>
<head>
<!-- <link rel="stylesheet" href="https://unpkg.com/mvp.css" /> -->
</head>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
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,
fontSize: 16,
}}
>
{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>
);
}
ReactDOM.render(<App />, root); // App을 root 안에 랜더링
</script>
</html>
결과 화면
위 코드를 살펴보면 changeValue 함수가 호출될 때, value 값이 재설정되고, value 값이 변경될 때 리렌더링 된다.
이때, App() function 내부 return (<div> ... </div>) 모두가 re-render 즉, 새로 그려진다.
현재 부모의 상태를 변경시키는 함수를 자식이 실행시킨다.
첫 번째 버튼의 props 값은 state와 연결되어 있기에 변경될 것이다.
여기서 이상한 부분은 두 번째 버튼까지 함께 다시 그려진다는 것이다.
(리액트는 컴포넌트의 상태가 변경되면 rerendering하게 되는데 rendering 할 필요가 없는 컴포넌트까지 rendering 한다.)
(이것은 애플리케이션이 느려지는 원인이 될 수 있다.)
이러한 문제를 해결해주는 것이 React.memo이다.
Memo를 사용하면 두 번째 컴포넌트가 다시 그려지는 것을 방지할 수 있다.
Memo를 추가한 코드
<!DOCTYPE html>
<html>
<head>
<!-- <link rel="stylesheet" href="https://unpkg.com/mvp.css" /> -->
</head>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
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,
fontSize: 16,
}}
>
{text}
</button>
);
}
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>
);
}
ReactDOM.render(<App />, root); // App을 root 안에 랜더링
</script>
</html>
결과 화면
두 번째 컴포넌트는 re-render 되지 않는 것을 확인할 수 있다.
'React > Props' 카테고리의 다른 글
Prop Types (0) | 2022.07.31 |
---|---|
Props (0) | 2022.07.28 |