Intro
- 두 개의 같은 디자인의 버튼을 만듬
- Props
- Memo
- Props Types
Props
일종의 방식. 부모 컴포넌트로부터 자식 컴포넌트로 데이터를 보낼 수 있게 해주는 방법
text가 다른 여러 button에 같은 style을 주고 싶을 때, 버튼 컴포넌트마다 style을 복사하는 건 비효율적이다.
따라서 style의 설정들을 넘겨줄 수 있는 button 컴포넌트를 하나 만들어서 재사용하는것이 좋다.
button 함수형 컴포넌트를 하나만들었다. 여기에 버튼마다 다른 text를 주려면 어떻게해야할까?
바로 여기서 사용하는 것이 Props이다. 커스텀 컴포넌트에 데이터를 전달시키기 위해 구문(syntax)를 이용한다.
img 태그의 src="" 라던지, button에 EventListner을 붙여주기 위해 onClick={}을 사용했던 것처럼 말이다.
<Btn text="Save Changes" big={true} />
<Btn text="Continue" big={false} />
여기서 text나 big 등 속성값의 이름을 무엇을 주든 상관없다. 커스텀 컴포넌트인만큼 자유롭다.
이제 우리가 준 데이터값을 컴포넌트 안에서 사용하기 위해서 Props를 사용한다. 모든 컴포넌트는 () 괄호로 argument(인자)를 받는데, 컴포넌트의 첫번째이자 유일한 인자를 props라고 부른다.
실제로 위 코드에서 React.js가 하는 작업은 Btn() 함수를 호출해서 우리가 넣어준 모든 것들을 첫번째 인자(props)에 넣어주는 것이다. 이 때, 데이터는 객체형식으로 들어가는데 Props를 console.log로 찍어보면 쉽게 확인할 수 있다.
function Btn(props) {
console.log(props);
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontsize: props.big ? 18 : 15
}}
>{props.text}</button>);
}
props는 객체이므로 사용할때 key값을 이용해 사용한다. props.text나 props.big과 같이 말이다.
하지만 보통 사람들은 shortcut(지름길) 사용하는데, property를 객체인 props로부터 꺼내는 방법이다. 다음과 같다.
function Btn({ text, big }) {
console.log(text, big);
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontsize: big ? 18 : 15
}}
>{text}</button>);
}
React.memo
우리는 버튼을 클릭했을 때 버튼의 text 내용이 변화되도록 state를 사용하려고 한다.
코드 작성 시 주의할 점은 props로 modified 함수를 주더라도 (아래서는 changeValue={changeValue}에 해당) 꼭 함수를 실행시키기 원하는 컴포넌트(Btn) 안에서 onClick 이벤트를 등록해줘야한다는 점이다!
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="Continue" />
</div>
);
}
< console.log 결과
컴포넌트에 로그를 찍어보면 state가 변경되는 버튼 뿐만아니라 continue 버튼도 함께 리렌더링 되는 것을 확인할 수 있다. 이는 부모 컴포넌트(APP)이 state(상태) 변경이 되고, 상태가 변경될 때 컴포넌트 전체가 리렌더링되기 때문이다.
하지만 우리는 continue 버튼을 리렌더링 할 필요가 없다. 이럴 때 사용할 수 있는게 React Memo 이다.
props가 변경되지 않았을때, 이 컴포넌트를 다시 그릴지 아닐지를 결정할 수 있게 해준다.
const MemorizeBtn = React.memo(Btn); // React memo
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Changes");
return (
<div>
<MemorizeBtn text={value} changeValue={changeValue} />
<MemorizeBtn text="Continue" />
</div>
);
}
memo 버튼 컴포넌트를 새롭게 추가해 수정해주고나면 continue 버튼은 리렌더링되지 않음을 확인할 수 있다.
만약 컴포넌트 안에 엄청 많은 컴포넌트를 그리고 있다고 하자. 부모 컴포넌트에서 state가 변경되었을 때 모든 자식 컴포넌트가 리렌더링된다면 어플리케이션이 느려지는 원인이 될 수 있다. memo는 이러한 점을 방지해준다.
Props Types
props에서 어떤 타입의 데이터를 받고있는지 체크(검사)하는게 가능하게끔 도와주는 패키지.
React JS에서는 내가 string을 넣으려던 타입에 number 타입을 넣는다해도 유효한 코드이기 때문에 에러를 보여주지 않는다. 이처럼 우리가 중요한 props 넣는걸 깜박한다거나, 잘못된 타입을 전달한다거나 하는 실수를 방지할 수 있도록 에러메세지(진짜 에러는 아닌 경고(warning))를 띄울 수 있다.
props types을 사용하기 위해선 설치가 필요하다. ( 밑의 script 추가 )
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
예시를 들자면, Btn의 text는 string을 받아야하며 그건 필수적이어야하고, fonsize number를 받아야한다는 검사를 하기 위해서 밑의 코드처럼 작성할 수 있다.
Btn.propTypes = {
text: PropTypes.string.isRequired,
fontSize: PropTypes.number,
}
'WEB > React' 카테고리의 다른 글
[React] API 사용하기 (0) | 2022.02.02 |
---|---|
[React] 배열 State (0) | 2022.02.02 |
[React] Effects (useEffect, clean-up) (0) | 2022.01.29 |
[React] State (0) | 2022.01.28 |
[React] Component, JSX (0) | 2022.01.26 |