[영화 웹] #4. PROPS

노마더코드 깃 히스토리: https://github.com/nomadcoders/react-for-beginners/commits/master
#4.0 Props
props는 부모 컴포넌트로부터 자식 컴포넌트에게 데이터를 전송하는 방식이다.
부모에 props를 사용하면 자식 컴포넌트(함수)의 인자로 객체가 들어가게 된다.
하나의 버튼을 만들어서 props를 이용해서 버튼의 스타일을 관리함으로써 재사용성이 높아진다.
https://devdocs.io/react/components-and-props
DevDocs
devdocs.io
App 컴포넌트에서 Btn 컴포넌트를 사용할때, <Btn text="hello" big={true} />처럼
사용자가 원하는 인자값을 Btn 컴포넌트에 넣어줄 수 있다.
인자값을 받을떄는 function Btn( { text, big }) {~~~} 처럼 파라미터를 객체로 기입해야 한다.
그러면 객체안의 변수들을 Btn 컴포넌트 안에서 그대로 사용할 수 있다.
이것보다 더 편한 방식이 function Btn (props) {~~~} 처럼 props를 이용하는 것이다.
props는 object type이므로 Btn컴포넌트 안에서 사용할때는 props.name 처럼 하면 된다.
장점 : 객체를 구조분해 할당 사용하면 매우 유용하다
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<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 }) {
console.log(text, big);
return (
<button
style={
{
background: 'tomato',
color: 'white',
padding: '10px 20px',
border: 9,
borderRadius: 10,
fontSize: big ? 18 : 8,
}
}
>
{text}
</button>
);
}
function App() {
return (
<div>
<Btn text="First btn props" big={true} />
<Btn text="Second btn props" big={false} />
</div>
); //<Btn text="~~"/> 는 실제로 Btn({text: "Save Changes"}) 와 같다
}
const root = document.querySelector('#root');
ReactDOM.render(<App />, root);
</script>
</body>
</html>
#4.1 Memo
일반적으로 컴포넌트 쓸 때 주의점 :
App 컴포넌트에서 Btn컴포넌트를 다음과 인자를 넣어주고 이와같이 썼다
<script type="text/babel">
function Btn(props) {
console.log(`${props.text} is rendered`);
return (
<button
onClick={props.onChangeValue}
style={
{
background: 'tomato',
color: 'white',
padding: '10px 20px',
border: 9,
borderRadius: 10,
fontSize: 16,
}
}
>
{props.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} onChangeValue={changeValue} />
<MemorizedBtn text="Continue" />
</div>
);
}
const root = document.querySelector('#root');
ReactDOM.render(<App />, root);
</script>
정리:
1. props에 function도 보낼 수 있다
이것은 JSX로 html 태그 자체에 이벤트 리스너를 넣는것과는 전혀 다른 것이다.
그저 이벤트를 실행시키는 함수가 프로퍼티로 들어간 것이다.
prop은 그냥 부모에서 자식으로 데이터를 넘길 때 사용하는 argument의 역할이니까!
2. (07:41~) 부모의 상태를 바꾸는 함수를 만들었고, 부모 컴포넌트에서 그 함수를 prop으로 보내면 자식 컴포넌트에서 그 함수가 실행된다.
3. 불필요한 re-render는 React.memo()로 관리할 수 있다
부모 컴포넌트의 state를 변경하면 당연히 그 자식 컴포넌트들도 Re-render가 일어남. 불필요한 렌더링이 발생할 수도 있는데, 이 경우에는 React.memo()로 prop의 변경이 일어난 부분만 렌더링 시킬 수 있음. 아주 많은 자식 컴포넌트를 가지고 있는 부모 컴포넌트일 때 사용하면 된다.
* React.memo()
컴포넌트가 React.memo()로 wrapping 될 때, React는 컴포넌트를 렌더링하고 결과를 메모이징(Memoizing)한다. 그리고 다음 렌더링이 일어날 때 props가 같다면, React는 메모이징(Memoizing)된 내용을 재사용한다.
#4.2 Prop Types
정리
1. Prop 은 component 에 보내는 argument 이다.
2. PropType을 이용해서 보내는 prop 에 type을 정의 할수 있다.
정의하는 이유는 잘못된 type의 prop 이 보내지는 것을 방지하기 위해서다.
PropType을 정의 했을때 React는 에러메세지를 통해서 잘못된 type이 보내지고 있다고 알려준다.
추가적인 기능: OPTIONAL하지 않고 REQUIRED한 PROPS를 주고 싶은 경우 등등 (참고사이트 참고)
근데 타입스크립트를 쓴다면 더이상 필요 없다.
https://ko.reactjs.org/docs/typechecking-with-proptypes.html
PropTypes와 함께 하는 타입 검사 – React
A JavaScript library for building user interfaces
ko.reactjs.org
<body>
<div id="root"></div>
<!-- <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> -->
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<!-- prop-types 적용 -->
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, fontSize = 14 }) {
return (
<button
style={
{
background: 'tomato',
color: 'white',
padding: '10px 20px',
border: 9,
borderRadius: 10,
fontSize,
}
}
>
{text}
</button>
);
}
Btn.propTypes = {
text: PropTypes.string,
fontSize: PropTypes.number.isRequired,
};
function App() {
return (
<div>
<Btn text="Save Changes" fontSize={20} />
<Btn text="Continue" />
</div>
);
}
const root = document.querySelector('#root');
ReactDOM.render(<App />, root);
</script>
</body>