[Props & Memo] Nomad Coders 영화 웹 서비스 만들기 #3
📑 Nomad Coders ‘ReactJS로 영화 웹 서비스 만들기’ 강의를 듣고 정리한 내용입니다.
Props
하나의 어플리케이션에는 여러 버튼들이 있고 그 버튼들은 모두 같은 디자인을 하고있다.
UI를 통일시키는게 디자이너의 일이다.
그러면 여러 버튼 컴포넌트들을 만들고 모두 같은 스타일을 넣어줘야 하는가?
그렇지 않다.
하나의 버튼을 만들고 그 안의 텍스트 내용이나 버튼을 눌렀을 때 기능만 다르게 넣어줄 수 있다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, big }) {
return (
<button
style=
>
{text}
</button>
);
}
function App() {
return (
<div>
<Btn text="Save Changes" big={true} />
<Btn text="Countinue" big={false} />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
컴포넌트의 괄호 안에 props를 적어준다.
prop의 이름은 마음대로 설정할 수 있다.
event도 넣어줄 수 있다.
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, changeValue }) {
console.log(text, " was rendered");
return (
<button
onClick={changeValue}
style=
>
{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="Countinue" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
이 때, 주의할 점은
렌더링 하는 부분에다가 onClick으로 넣으면 eventListener가 되는게 아니라는 점이다.
그 안에 들어가는 내용은 모두 property
가 될 뿐이다.
그래서 위에 컴포넌트 안에서 onClick으로 함수를 넣어줘야 한다.
이 때 우리가 11번 째 줄에서 console.log(text, “ was rendered”)
해준 부분을 살펴보면
버튼은 하나만 바뀌는데 둘 다 리렌더 되는 것을 알 수 있다.
왼쪽 버튼만 바뀌고 오른쪽은 그대로니까 리렌더 될 필요가 없는데 말이다.
이럴 때는 React.memo
를 사용해서 만약 props가 변경되지 않는다면 해당 컴포넌트가 리렌더되는 것을 원치 않는다고 알려줄 수 있다.
React.memo()
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, changeValue }) {
console.log(text, " was rendered");
return (
<button
onClick={changeValue}
style=
>
{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="Countinue" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
위와 같이 MemorizedBtn
에 React.memo()
도구를 사용해주고 괄호 안에는 위에서 만들었던 Btn
컴포넌트를 입력해준다.
이렇게 하면 우리가 만든 Btn을 기억하고있다가 변경되는 부분만 리렌더 하도록 도와줄 것이다.
콘솔에서 확인해 본 결과, text prop이 바뀐 버튼만 리렌더 된 것을 알 수 있다.
propTypes
마지막으로 propTypes에 대해서 알아보자.
우리가 props로 하나의 컴포넌트를 만들어서 여러가지 방법으로 재사용 할 수 있다는 점을 알았다.
하지만 실수로 prop에 다른 값을 전달했다고 생각해보자.
function App() { return (
<div>
<Btn text="Save Changes" fontSize="{18}" />
<Btn text="{14}" fontSize="Continue" />
</div>
); }
위처럼 예상했던 값과 전혀 다른 값을 전달했다고 가정하고 실행해보면
아래 처럼 정상적으로 실행된다.
아무런 경고나 오류도 나오지 않는다.
이 때, prop에 맞는 type을 입력해 줄 수 있도록 경고를 띄워줄 수 있다.
먼저 아래와 같은 script로 propTypes를 설치해준다.
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
그리고나서 해당 컴포넌트의 각 prop들이 어떤 type을 가질 것인지 설정해준다.
Btn.propTypes = { text: PropTypes.string, fontSize: PropTypes.number, };
그리고 다시 실행해보면 아래 사진처럼 실행은 되지만 친절하게 경고 문구를 띄워주는 것을 볼 수 있다.
💫 isRequired
Btn.propTypes = {
text: PropTypes.string.isRequired,
fontSize: PropTypes.number.isRequired,
};
뒤에 isRequired
를 붙여주면
function App() {
return (
<div>
<Btn text="Save Changes" fontSize="{18}" />
<Btn text="Continue" />
</div>
);
}
이런 상황에서
.
이런 에러를 받을 수도 있다.
💫 default value
혹은 아래처럼 props 안에서 default value를 설정해 줄 수도 있다.
(react기능은 아니다. )
function Btn({ text, fontSize = 10 }) {
return (
<button
style=
>
{text}
</button>
);
}
Leave a comment