오늘은 기분이 좋다.
왜냐면 어제 진~ㅉㅏ 많이 먹었는데 먹고 누워서 책 읽고 핸드폰 하다 디비 자니까 행복했다.
먹고 싶었던 500kcal가 넘는 아주 맛있는 과자를 혼자 다 먹었다.
(마라탕, 밥 두공기, 제육볶음, 강된장, 온갖 쌈, 과자, 아이스크림 ...내 혈당은 누가 막아주지?)
그런데 오늘도 많이 먹을거라서 기분이가 좋다.
기운이 딸려서 먹고 힘 좀 내야겠어!
무튼 오늘 공부한 props를 정리해보겠다.
('초보자를 위한 리액트200제'를 통해 공부한 내용을 복기하는 시간입니다.
모든 내용과 코드는 위 책을 통해서 적었습니다!)
🧚♂️Props?
props는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달할 때 사용한다.
특이점은 props를 전달받은 자식 컴포넌트에서는 데이터 수정 X
그래서 데이터를 변경하려면 컴포넌트 내부에서만 사용하는 변수에 값을 넣어서 사용해야 한다.
위 말이 조금 어렵게 느껴졌고, 피부로 와닿지 않는다.
지피티에게 예시 코드를 받았다.
// 부모 컴포넌트에서 자식 컴포넌트에 name과 age를 전달
<ChildComponent name="John" age={30} />
// 자식 컴포넌트
function ChildComponent(props) {
return <p>{props.name} is {props.age} years old.</p>;
}
//props는 부모가 전달해준 값을 단순히 읽고 표시하는 역할을 하며,
//자식 컴포넌트에서는 그 값을 변경할 수 없다.
//만약 자식 컴포넌트에서 props를 변경해야 한다면,
//부모 컴포넌트가 그 값을 변경한 뒤 다시 자식에게 전달해야 합니다.
//데이터를 변경하려면 컴포넌트 내부에서 사용하는 변수를 사용해야 한다.
//데이터를 수정하고 싶을 때는 컴포넌트 내부에서 state를 사용해야 한다.
//state는 컴포넌트 내부에서 관리되는 데이터로, 해당 데이터를 변경하고 다시 렌더링
class ChildComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 }; // 내부 상태 관리
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 }); // state 변경
}
render() {
return (
<div>
<p>{this.props.name} has clicked {this.state.count} times.</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
요약하자면,
props는 부모로부터 자식에게 데이터를 전달하는 용도이며, 자식 컴포넌트는 이 데이터를 수정할 수 없다.
데이터를 변경하고 싶다면, 컴포넌트 내부에서 state를 사용해 내부 데이터를 관리해라! 이 말씀!
🏌️♂️props에서 데이터 사용해보기
import { Component } from "react";
class R017_Props extends Component{
render(){
let props_value = this.props.props_val;
props_value += ' from App.js'
return(
<div>{props_value}</div>
)
}
}
export default R017_Props;
여기서 신기했던 점은
this.props.뒤에 상위 컴포넌트(App.js)에서 전달받은 props변수명을 붙이면 해당 데이터를 쓸 수 있다.
`App.js 파일 <Props props_val="이것 프롭스다!"/>` => 그럼 화면에 이것 프롭스다! 라고 띄워진다.
🏌️♂️props 자료형 선언
import { Component } from "react";
import datatype from 'prop-types'; // prop-types 라이브러리 임포트
// 클래스형 컴포넌트 정의
class R018_PropsDatatype extends Component {
render() {
// props에서 전달된 값을 구조분해 할당으로 추출
//구조분해 할당을 사용하지 않으면, this.props로 모든 값을 참조해야 함
let {
String, Number, Boolean, Array, ObjectJson, Function
} = this.props
return (
<div style={{padding: "0px"}}> {/* 스타일 적용 */}
{/* props로 전달된 String 값 출력 */}
<p>StringProps: {String}</p>
{/* props로 전달된 Number 값 출력 */}
<p>NumberProps: {Number}</p>
{/* props로 전달된 Boolean 값을 문자열로 변환 후 출력 */}
<span>BooleanProps: {Boolean.toString()}</span>
{/* props로 전달된 Array 값을 문자열로 변환 후 출력 */}
<p>ArrayProps: {Array.toString()}</p>
{/* props로 전달된 ObjectJson을 JSON 문자열로 변환 후 출력 */}
<p>ObjectJsonProps: {JSON.stringify(ObjectJson)}</p>
{/* props로 전달된 Function을 출력 */}
<p>FunctionProps: {Function}</p>
</div>
)
}
}
// propTypes를 이용해 props의 데이터 타입을 정의
R018_PropsDatatype.propTypes = {
String: datatype.string, // String은 문자열이어야 함
Number: datatype.number, // Number는 숫자여야 함
Boolean: datatype.bool, // Boolean은 불리언 타입이어야 함
Array: datatype.array, // Array는 배열이어야 함
ObjectJson: datatype.object, // ObjectJson은 객체여야 함
Function: datatype.func // Function은 함수여야 함
}
export default R018_PropsDatatype; // 컴포넌트 내보내기
자식 컴포넌트에서 props에 대한 자료형을 선언해 놓으면,
부모 컴포넌트에서 넘어오는 props변수들의 자료형과 비교한다. 이때 자료형이 일치하지 않는다면, 경고 메시지로 알려주기에 잘못된 데이터를 파악하기 좋다.
처음에 let으로 구조분해 할당을 왜 하는지 궁금해서 찾아봤다.
let으로 구조분해 할당을 하지 않으면, props를 사용할 때마다 this.props.String, this.props.Number 등으로 참조해야 한다고 한다. 즉 단순화와 코드 가독성을 높이기 위함.
🏌️♂️props Boolean 사용하기
import { Component } from "react";
import datatype from 'prop-types'; // prop-types 라이브러리 임포트
// 클래스형 컴포넌트 정의
class R019_PropsBoolean extends Component {
render() {
// props에서 BooleanTrueFalse 값을 구조분해 할당으로 추출
let {
BooleanTrueFalse
} = this.props;
return (
<div style={{padding: "0px"}}> {/* 스타일 적용 */}
{/* BooleanTrueFalse가 true일 때 '2.' 출력, false일 때 '1.' 출력 */}
{BooleanTrueFalse ? '2.' : '1.'}
{/* BooleanTrueFalse 값을 문자열로 변환 후 출력 */}
{BooleanTrueFalse.toString()}
</div>
);
}
}
export default R019_PropsBoolean; // 컴포넌트 내보내기
props값을 Boolean형으로 하위 컴포넌트에 전달할 경우, true나 false 중 하나를 할당한다.
props 변수를 선언한 후 값을 할당하지 않고 넘기면 true가 기본값으로 할당된다.
그래서 BooleanTrueFalse 변수가 false일 경우 그대로 false가 출력되고,
값이 없을 경우 기본값으로 true가 화면에 출력된다.
Boolean 변수는 직접 화면에 출력할 수 없어서 tostring()함수를 사용해 문자열로 변환
🏌️♂️props 객체형으로 사용하기
import { Component } from "react";
import datatype from 'prop-types'; // prop-types 라이브러리 임포트
// 클래스형 컴포넌트 정의
class R020_PropsObjVal extends Component {
render() {
let {
ObjectJson
} = this.props
return (
<div style={{padding: "0px"}}> {/* 스타일 적용 */}
{JSON.stringify(ObjectJson)}
</div>
);
}
}
R020_PropsObjVal.propTypes={
ObjectJson: datatype.shape({
react: datatype.string,
twohundred: datatype.number
})
}
export default R020_PropsObjVal; // 컴포넌트 내보내기
props 값을 객체로 전달할 때, 자료형을 object로 선언한다.
하지만 객체 내부 변수들의 자료형을 선언할 때는 shape이라는 유형을 사용
🏌️♂️props를 기본값으로 정의하기
import { Component } from "react";
// 클래스형 컴포넌트 정의
class R022_PropsDefault extends Component {
render() {
// props에서 ReactString, ReactNumber 값을 구조분해 할당으로 추출
let {
ReactString,
ReactNumber
} = this.props;
return (
<div style={{padding: "0px"}}> {/* 스타일 적용 */}
{/* ReactString과 ReactNumber 값을 출력 */}
{ReactString}{ReactNumber}
</div>
);
}
}
// propTypes를 사용하여 prop의 데이터 타입을 지정하고, 필수 prop 설정
R022_PropsDefault.propTypes = {
ReactString: "리액트", // ReactString은 필수이며, 문자열이어야 함
ReactNumber: 400 // ReactNumber는 숫자 타입이어야 함 (선택 사항)
}
export default R022_PropsDefault; // 컴포넌트 내보내기
props의 기본값은 부모 컴포넌트에서 값이 넘어 오지 않았을 때 사용.
그 때! defaultProps라는 문법을 사용한다.
app.js에서는 ReactNumber={200} 값을 전달했다.
위 코드를 보면 ReactString, ReactNumber 변수에 각각 기본값을 할당한 상태
ReactString 변숫값은 비어 있어서 ReactString: "리액트"로 지정한 기본값이 화면에 출력
반면 ReactNumber는 상위컴포넌트에서 {200}이라는 값이 전달됐기 때문에 400이란 값은 무시된다.
👨💻정리해볼게! 얍!
이 예시들로 리액트 기본 로직들이 이해가 되기 시작했다.
오늘 개발자 관련 책을 읽으면서 하나 깨달은 점이 있다.
<모든 코드는 존재 이유가 있으며, 그 코드들이 만들어졌을 때는 분명한 의도를 가지고
만들어졌다. >
나는 한 번도 이 코드가 왜 생겼을지 생각을 해본적이 없다.
그냥 익숙하게 사용했을 뿐.
그렇지만 이 코드가 언제 어떻게 쓰이는 지 명확하게 알고 사용한다면,
코드를 짜는 데 있어서 더 효율적으로 일을 할 수 있지 않을까?
삐약이 개발자니까 더욱 기반을 탄탄하게 하고 싶다.
그럴려면 내가 제일 잘하고 싶은 언어를 골라서 좀 깊게 세세하게 파본다면,
다음 최신 언어를 만나도 무섭지 않지 않을까?
(라틴어에서 영어가 파생된 것처럼..) 개발 언어도 파생 되는 게 많으니까!
아무튼 조금 귀찮고 하기 싫어도 꼭 필요한 과정이라고 생각하고 해야겠다!
'developer Studying > React' 카테고리의 다른 글
[react] Component와 Component의 라이프 사이클(Lifecycle) (2) | 2024.09.09 |
---|---|
[react]Map()함수 (3) | 2024.09.06 |