이번엔 props 를 이해하기 위해
버튼 컴포넌트를 이용한 실습을 해볼 것이다.
#4. Props
props
부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법
자식 컴포넌트의 첫 번째이자 유일한 인자 (argument) 이다.
text, boolean, function, ... 등 어떤 형태로든 보낼 수 있다.
Practice - (1) 여러 개의 버튼 만들기
function SaveBtn() {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>Save Changes</button>
)
}
function ConfirmBtn() {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>Confirm</button>
)
}
function App() {
return (
<div>
<SaveBtn />
<ConfirmBtn />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
SaveBtn 과 ConfirmBtn 컴포넌트 생성
-> 버튼을 만들 때마다 style 을 복사해서 사용해야 함 => 비효율적
어차피 버튼 글자만 다른건데... 하나로 만들자!!
Practice - (2) Props 전달
부모 컴포넌트의 Props 전달
<Btn text="Save Changes"/>
<Btn text="Continue"/>
전달할 property = 값 의 형태로 Props 전달
property 의 이름은 원하는대로 지어도 상관 없음 ex) text, tomato, ...
자식 컴포넌트가 Props 를 받아오는 방식 1
function Btn(props) {
return (
<button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{props.text}</button>
)
}
props 라는 argument 를 받아서 props.text 형태로 사용
자식 컴포넌트가Props 를 받아오는 방식 2
function Btn({text}) {
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{text}</button>
)
}
props 는 오브젝트이기 때문에 가져올 property 의 이름을 { } 와 함께 바로 사용하기도 함
주의할 점, 보내는 property 이름과 받는 property 이름이 일치해야 한다.
보통은 2번째 방식을 많이 사용함
일부 Props 만 전달할 경우
<Btn text="Save Changes" index={1}/>
<Btn text="Continue"/>
만약 Continue 버튼이 index 를 전달하지 않았다면
=> Btn 컴포넌트는 undefined 를 받게 됨
이럴 경우를 대비해 default 값을 설정할 수 있다.
function Btn({text, fontSize = 14}) { ... }
style 에서의 Props 사용
function Btn({text, fontSize}) {
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize: fontSize
}}>{text}</button>
)
}
function App() {
return (
<div>
<Btn text="Save Changes" fontSize={20}/>
<Btn text="Continue" fontSize={16}/>
</div>
);
}
props 는 style 에서도 사용 가능하다.
fontSize 를 받아와서 사용
fontSize: fontSize => 이름이 같기 때문에 fontSize 만 써도 O
function Btn({text, index}) {
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize: index === 1 ? 20 : 16
}}>{text}</button>
)
}
function App() {
return (
<div>
<Btn text="Save Changes" index={1}/>
<Btn text="Continue" index={2}/>
</div>
);
}
style 에서 삼항 연산자를 이용해 적용할 수도 있다.
Practice - (3) Props 로 함수 전달
function Btn({text, changeValue}) {
return (
<button
onClick={changeValue}
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{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>
);
}
Save Changes 버튼을 클릭하면 Revert Changes 버튼으로 바뀌도록 해보자.
App()
value 라는 state 를 이용해 버튼 상태 저장
changeValue 는 Revert Changes 로 value 를 바꾸는 함수
Btn 컴포넌트로 value 와 changeValue 를 넘겨준다.
Btn 컴포넌트
changeValue 함수를 받아와 버튼 onClick 에 적용
커스텀 컴포넌트에 전달하는 onClick 함수는 이벤트 리스너가 아니다.
HTML 요소에 넣어야 이벤트 리스너가 됨
=> button 태그를 위한 이벤트 리스너가 아닌 Btn 컴포넌트를 위한 props 일 뿐
결과
Prop-Types
만약, Props 로 넘기는 값에 실수를 할 경우 -> 문법 상의 오류는 없지만 구현 상의 오류 발생 가능
=> Prop-Types 를 이용하면 예방할 수 있다.
https://unpkg.com/prop-types@15.7.2/prop-types.js 추가
사용법
Btn.propTypes = {
text: PropTypes.string,
fontSize: PropTypes.number
}
예시
<Btn text="Continue" fontSize={"hi"}/>
fontSize 는 number 로 지정해뒀지만 문자열을 입력할 경우
=> 에러 발생까지는 아니지만 최소한의 경고문을 볼 수 있음
propTypes 가 적용 되지 않는 경우,
https://unpkg.com/react@17.0.2/umd/react.production.min.js 를 https://unpkg.com/react@17.0.2/umd/react.development.js 로 수정
- https://ko.reactjs.org/docs/typechecking-with-proptypes.html => propTypes 공식 문서
- required 를 이용하면 필수적으로 해당 property 가 존재하도록 지정 가능
- TypeScript 를 사용하면 필요 없는 기능이다.
참고) React Memo
- 기억할 필요는 없으며 이런 게 있다는 것만 알아두기...
부모 컴포넌트가 state 변경을 겪으면 모든 게 새로 그려진다.
(Save 버튼과 Continue 버튼이 같이 그려짐)
-> 추후 어플리케이션이 느려지는 원인이 될 수 있음
React Memo 는 props 가 변할 때만 re-render 하게 할 수 있다.
(Continue 는 그려지지 않음, 새로운 버튼만 그려짐)
function Btn({text, changeValue}) { ... }
const MemorizedBtn = React.memo(Btn);
function App() {
...
return (
<div>
<MemorizedBtn text={value} changeValue={changeValue}/>
<MemorizedBtn text="Continue"/>
</div>
);
}
여기까지 ReactJS 의 기본 지식을 배워보는 시간이었다.
다음 강의부터는 본격적으로 React 사용 시작!!
전문적인 방식으로 ReactJS 를 구현할 것이다.
'FrontEnd > React' 카테고리의 다른 글
[ReactJS] Effect - ReactJS 로 영화 웹 서비스 만들기 (6) (0) | 2021.12.02 |
---|---|
[ReactJS] Create React App - ReactJS 로 영화 웹 서비스 만들기 (5) (0) | 2021.11.26 |
[ReactJS] Unit Converter 완성 - ReactJS 로 영화 웹 서비스 만들기 (3) (0) | 2021.11.25 |
[ReactJS] State - ReactJS 로 영화 웹 서비스 만들기 (2) (0) | 2021.11.25 |
[ReactJS] Introduction & The Basics of React - ReactJS 로 영화 웹 서비스 만들기 (1) (0) | 2021.11.24 |
댓글