props
는 부모 컴포넌트가 자식 컴포넌트에게 주는 값이다.
자식 컴포넌트에서는 props
를 받아오기만하고, 받아온 props
를 직접 수정 할 수 는 없다.
- (자식 입장에서) 읽기 전용
- 부모 요소에서 설정하는 것
- 초깃값과 자료형의 유효성 검사 가능
- 상속하는 부모 컴포넌트로부터
props
를 받고, 이 props는 상속받은 컴포넌트(=자식 컴포넌트) 내에서 수정이 불가능하다.- props는 컴포넌트가 가지고 있는 다양한 값을 나타내기 위해서
this.props.000
로나타낸다.
state
는 컴포넌트 내부에서 선언하며 내부에서 값을 변경 할 수 있다.
- 컴포넌트의 상태를 나타낸다. 상태에 따라 변화하는 것.
- props와 반대로, 변할 수 있는 속성이다. (컴포넌트 내부에서 선언되기 때문, 직접 변경 가능)
state
가 변경되면 컴포넌트를 다시리렌더링
해야 한다.
❗this.setState()
구성요소에서 호출하여 업데이트 ➡ 기존 state를새로운 state
로 대체 ➡render()
실행state
는 외부에 공개하지 않고, 컴포넌트가 스스로 관리한다- state로 사용하는 것은, 컴포넌트의 상태값을 나타내기 위한 것들이다
ex) list에서 선택된 값, check-box에서 체크된 값, text-box의 텍스트 등
// 자식 component 예시 import React, {Component} from "react"; class Student extends Component { render() { return ( <div className="Student"> <h3> 이름: {this.props.name} </h3> <h3> 소속: {this.props.department} </h3> <h3> 연락처: {this.props.phone} </h3> <h3> 이메일: {this.props.email} </h3> </div> ); } } export default Student;
// 부모 component 예시 import React, {Component} from "react"; import Student from "./Student"; class App extends Component { render() { return ( <div className="App"> <Student name: "leedev" department: "Dev" phone: "010-123-1234" email: "leedev@gmail.com" /> </div> ); } } export default App; // 부모 Component(App.js)에서 지정한 name, department, phone, email이 // 자식 Component(Student.js)로 전달되어 // Student에서 `this.props.name`, `this.props.department`, `this.props.phone`, `this.props.email`이 사용된다.
🪐 defaultProps
자식 Component
에서는 defaultProps
를 이용하여 props의 기본값을 설정해 줄 수 있다.
이 값은 부모 Component에서 지정해 줄 경우 지정한 값으로 지정하지 않을 경우 기본값으로 props가 적용된다.
// 자식 component에 defaultProps 적용 예시 import React, {Component} from "react"; class Student extends Component { // 기본 props 지정 static defaultProps = { department: "Dev" } render() { return ( <div className="Student"> <h3> 이름: {this.props.name} </h3> <h3> 소속: {this.props.department} </h3> <h3> 연락처: {this.props.phone} </h3> <h3> 이메일: {this.props.email} </h3> </div> ); } } export default Student;
// 부모 component 에서 defaultProps 값 적용예시 import React, {Component} from "react"; import Student from "./Student"; class App extends Component { render() { return ( <div className="App"> // department 값 생략 <Student name: "leedev" phone: "010-123-1234" email: "leedev@gmail.com" /> // department 값 포함 <Student name: "kimdev" department: "Dev" phone: "010-234-1142" email: "kimdev@gmail.com" /> </div> ); } } export default App; // 2개의 Student 컴포넌트 값의 결과는, 동일하게 department 값 포함한다
🪐 Functional Component(함수형 컴포넌트)
props
를 받아와 보여주기만 하는 컴포넌트의 경우 더 간단한 문법으로 사용할 수 있다. static
이나 this
키워드를 사용할 수 없다. 그리고 state
나 Life Cycle
과 관련된 함수를 사용할 수 없다. // Student.js import React from "react"; const Student = ({ name, department, phone, email }) => { return ( <div className="Student"> <h3> 이름 : <b>{name}</b> </h3> <h3> 소속 : <b>{department}</b> </h3> <h3> 연락처 : <b>{phone}</b> </h3> <h3> 이메일 : <b>{email}</b> </h3> </div> ); }; // 기본 props 지정(함수형 컴포넌트 사용시 static을 사용불가) Student.defaultProps = { department: "Dev" }; export default Student;
선언된 state 값을 변경하기 위해서는 무조건 this.setState
를 사용해야 한다.
React 내부에서 setState를 호출하게 되면 자동으로 Component를 리렌더링하게 설계되어있다.
객체로 전달되는 해당 값만 state에서 변경된다. ➡ 전달되지 않은 값은 기존값으로 유지.
기존의 값을 토대로 새로운 값으로 변경하고 싶을 땐 "값1: this.state.값1"
이런 식으로 처리를 한다. this.state를 사용하고 싶지않다면 setState를 화살표 함수
로 만들어서 매개변수로 state나 해당 값을 넣어주면 된다.
이 때, 해당 값을 이용할 땐 비구조화 할당(Destructuring Assignment)이라는 문법을 사용합니다.
// 자식 component 예시 import React, { Component } from "react"; class StopWatch extends Component { // state를 객체 형태로 전달 state = { sec: 0, buttonFlag: true, intervalFunction: null }; // stop watch 함수 로직 ➡ setState 사용 timer = () => { this.setState(({ sec }) => ({ // 비구조화 할당 사용( { sec } 부분 ) sec: sec + 1 })); }; // start 버튼 클릭 함수 로직 ➡ setState 사용 start = () => { this.setState({ sec: 0, buttonFlag: false, intervalFunction: setInterval(this.timer, 1000) }); }; // stop 버튼 클릭 함수 로직 ➡ setState 사용 stop = () => { clearInterval(this.state.intervalFunction); this.setState({ buttonFlag: true }); }; render() { return ( <div className = "StopWatch"> <h1>Stop Watch</h1> <div> <b>{this.state.sec}</b> <span>초</span> {this.state.buttonFlag ? ( <button onClick={this.start}>start</button> ) : ( <button onClick={this.stop}>stop</button> )} </div> </div> ); } } export default StopWatch;
// 부모 component 예시 import React, { Component } from "react"; import StopWatch from "./StopWatch"; class App extends Component { render() { return <StopWatch />; } } export default App;
// state와 setState를 활용하여 동적 데이터 만들기 // 자식 component (Counter) import React, { Component } from 'react'; class Counter extends Component { // class fields 문법 state = { number: 0 } // ❗ class fields 문법 대신 constructor를 사용한다면? // constructor(props) { // super(props); // this.state = { // number: 0 // } // } // ❗ 꼭 화살표 함수로 정의해주기 handleIncrease = () => { this.setState({ number: this.state.number + 1 }); } handleDecrease = () => { this.setState({ number: this.state.number - 1 }); } render() { return ( <div> <h1>카운터</h1> // 값에 들어가는 숫자는 state의 number값을 넣어준다 <div> 값: {this.state.number} </div> // ❗ 이벤트이름을 설정 할 때 camelCase 로 설정해주기!! (onClick, onChange...) <button onClick={this.handleIncrease}> + </button> <button onClick={this.handleDecrease}> - </button> </div> ); } } export default Counter;
// 부모 component (App) import React, { Component } from 'react'; import Counter from './Counter'; class App extends Component { render() { return ( <Counter /> ); } } export default App;
어 이거 리액트를 다루는 기술 책보면서 하나요 새봄님? ㅎㅎ