리액트 모든 컴포넌트가 가지고 있는 내장 객체
부모컴포넌트로부터 전달 받은 데이터를 지니고 있는 객체
props는 부모에서 넘겨주는 속성 —> 읽기 전용
속성(props)
을 부여받는 것은 상위 존재가 정해주는 것.
읽기전용의 속성이라고 보면 된다.
부모가 주는 것을 받아서 자식은 읽기만 할 수 있음.
컴포넌트에 속성을 부여하는 것.
컴포넌트는 모든 속성을 부여 받는다.
state의 상태 값, event handler를 넘겨 줄 수 있다.
스트링을 제외한 데이터타입은 { } 로 표현...
→ 자바스크립트이기 때문에{ this.props.name }
재사용 가능 및 제한이 없음.
class Parent extend Component {
introduce = ( ) => {
alert("Hello");
}
render() {
return (
<div>
<Child name="me" age={0} introduce={this.introduce} />
<Child name="Minji" age={1} introduce={() => alert("Good morning")} />
</div>
);
}
}
class Child extend Component {
render() {
return (
<div>
<h1 onClick={ this.props.introduce }>
Name: {this.props.name} Age: {this.props.age}
</h1>
</div>
// 렌더링 하면,
// Name: me Age: 0 --> click 하면 alert 창으로 "Hello" 가 뜸
// Name: Minji Age: 1 --> click 하면 alert 창으로 "Good morning"이 뜸
);
}
}
class 안에서
this
는 해당 class 객체를 가리킨다.
함수를 선언 할 땐 화살표함수를 쓴다.
이유는?!this
때문이다.!
this
가 그때그때 상황에 따라서 동적으로 결정되는데, 이 때 함수들이 props로 다른 컴포넌트로 넘어가서 호출되면 다른 컴포넌트를 가르키는this
로 가르키기 때문에this
가 달라져서 오류가 난다.!그러나
화살표함수
는 함수가 선언된 그 장소에서 고정된 값으로 해당 컴포넌트를 가지고 있다.
즉, 화살표함수는this
가 고정되어 있고, 일반함수는 호출되면this
를 엉뚱하게 인식을 하고, 제대로 값을 가져오지 못할 수도 있기 때문에.!
컴포넌트에서 함수선언 할 때에는 꼭 화살표함수를 선언해야 한다.
컴포넌트가 가지고 있는 값.
UI를 그리는데 필요한 것을 담고 있는 state라는 객체
변하지 않는 값들은
class component
밖에서const 변수
선언.
state에는변하는 값
을 넣어준다.
class component 안에constructor()
와super()
가 필수.!
super()
함수가 호출되면 해당 컴포넌트가 상속하고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다.
class Parent extend Component {
constructor() {
super();
this.state = {
titleColor:"red",
subTitleColor:"green"
}
}
render() {
return (
<div>
<h1 style={{ color: this.state.titleColor }} >부모타이틀!</h1>
// JSX 문법에서는 인라인 스타일 줄 때, 객체형식으로 주어야 하기 때문에 총 2개의 중괄호가 생긴다.
// 밖에 있는 {}는 자바스크립트라는 것을 알려주는 것이고,
// 안에 있는 {}는 객체형태를 나타내는 중괄호이다.
</div>
);
}
}
state는 컴포넌트 안에서 스스로 변경하는 것. —>
setState
를 통해 값을 변경할 수 있다.
state
값은 직접적으로 바꿀 수 없고,
리액트의 구조상setState
를 호출이 된 다음에는 render 함수를 다시 호출하라고 되어 있다.
class 기반으로 생성되는 경우는setState
를 활용하고,
function 기반으로 생성되는 경우는useState
를 활용한다.
event를 통해 state 변경
이벤트를 이용하여 state를 바꿀 수 있음.
class Parent extends Component {
constructor () {
super();
this.state= {
titleColor:"red"
// state의 값 초기화 설정.
};
}
}
changeTitleColor= () => {
this.setState({
titleColor:"blue"
});
}
// setState라는 함수에 객체형식으로 변경될 값을 넣어준다.
// 리액트 컴포넌트 안에 있는, 내재되어 있는 함수. 겹치면은 마지막에 있는 것으로 덮여쓰여짐.
render() {
return (
<>
<h1 style={{ color: this.state.titleColor }}>현재 부모타이틀은 레드</h1>
<button onClick= {this.changeTitleColor} 버튼 누르면 블루!/>
</>
)
}
component 에게 적용하는 (html에서 속성인) props 는 사용자에게 중요한 정보.!
그러나, state는 component 내부적으로 사용되는 것. 사용자들이 알 필요가 없음
props의 값이나 state의 값이 변경되면 자동으로 해당 컴포넌트의 랜더함수가 호출되도록 되어 있다.
state와 변수의 차이점은 state는 재렌더링되고, 새로고침하지 않아도 되는 장점~~~!
하나의 설정 값으로부터 다른 값으로 전환.
두 가지 상태 밖에 없는 상황에서 스위치를 한번 누르면 한 값이 되고, 다시 한번 누르면 다른 값으로 변하는 것을 의미한다.
state를 true/false의 값으로 변경하고, 삼항연산자를 이용하여 toggle 구현할 수 있다.
class Parent extends Component {
constructor () {
super();
this.state= {
isButtonClicked: false
// 객체 생성~
};
}
}
changeTitleColor= () => {
this.setState({
isButtonClicked: !this.state.isButtonClicked
// 여기서 'isButtonClicked'는 단순 string 키 이름.
// 키값은 toggle을 위해 해당 state의 반대의 값을 할당해야 해서
// 'this.state'로 접근하여 state의 값을 가져와서 '!'로 반대의미 부여
});
}
render() {
return (
<>
<h1 style={{
color: this.state.isButtonClicked ? "red" : "blue"
// 삼항연산자를 이용하여 toggle 완성.
// state의 값이 true 면 "red", 아니면 "blue"
// 조건문에 'this.state.isButtonClicked === true' 로 표현 안한 이유는 자체가 boolean 값이기 때문!
}}>현재 부모타이틀은 레드</h1>
<button onClick= {this.changeTitleColor} 버튼 누르면 블루!/>
</>
)
}
h1
와button
은 직접적인 연관은 없지만state의 값을 통해 연결
되어 있다.
button은 click Event로 state의 값만 바꿔주고 있다.
state의 값에 따라 h1의 스타일링이 바뀌고 있다.
객체나 배열의 구조를 분해해서 객체 안에 있는 키 값과 동일한 이름으로 변수를 만들어서 사용.
import React from 'react';
class Parent extends React.Component {
constructor () {
super();
this.state= {
isButtonClicked: false
};
}
}
changeTitleColor= () => {
const { isButtonClicked } = this.state;
// 지역변수로 state 초기값을 구조분해 할당 함.
this.setState({
isButtonClicked: !isButtonClicked
// 여기서 'this.state' 생략!!
});
}
render() {
const { isButtonClicked } = this.state;
// constructor 안에 생성된 state 초기값을 구조분해 할당 함.
return (
<>
<h1 style={{
color: isButtonClicked ? "red" : "blue"
// 여기서 'this.state' 생략!!
}}>현재 부모타이틀은 레드</h1>
<button onClick= {this.changeTitleColor} 버튼 누르면 블루!/>
</>
)
}
여기서 구조분해할당에 변수를 여러개 넣을 수 있다.
import React from 'react';
class Parent extends React.Component {
constructor () {
super();
this.state= {
isButtonClicked: false,
childTitleColor: "green"
// state의 키를 두개로 만듬
};
}
}
changeTitleColor= () => {
const { isButtonClicked } = this.state;
this.setState({
isButtonClicked: !isButtonClicked
});
}
render() {
const { isButtonClicked, childTitleColor } = this.state;
// state의 키이름들을 한 개의 변수에 넣을 수 있음.
return (
<>
<h1 style={{
color: isButtonClicked ? "red" : "blue"
}}>현재 부모타이틀은 레드</h1>
<button onClick= {this.changeTitleColor} 버튼 누르면 블루!/>
<Child childTitleColor= {childTitleColor} />
// Child 컴포넌트의 props 상속.
</>
)
}
Child 컴포넌트에서 확인!
import React from 'react';
class Child extend React.Component {
render() {
console.log('this.props', this.props);
// console로 찍어봐서 해당 props 값을 가지고 오는지 확인 가능.
const { childTitleColor } = this.props;
return (
<>
<h2 style= {{
color: childTitleColor}}> 여기는 자식 컴포넌트으~ </h2>
// 여기서 'this.props' 생략하고 childTitleColor만 가지고 옴.
// 이유는 위에 구조분해 할당하였기 때문에!
</>
)
}
}
자식은 부모의 state를 직접적으로 변경 할 수 없다.
그러나 부모 내에서 변경하는 함수를 만들고, 그 함수를 자식에게 props로 전달을 함으로써 값을 변경할 수 있음.
리액트는 부모에서 자식으로 데이터를 보내는 한방향, 단방향.
같은 형제관계에서는 서로 접근을 할 수가 없음