React_State & Props

Minji Jeong·2021년 9월 19일
0

React

목록 보기
2/9
post-thumbnail

React를 사용하면 화면을 컴포넌트 단위로 구분해서 구현한다.
Nav, Main, Footer로 나뉘어져 있을 것이고, 또 Main은 프로필 컴포넌트, 제품 설명 컴포넌트를 가지고 있을 것이다.
따라서 부모 컴포넌트 아래에 자식 컴포넌트가 속해 있는 구조가 되고,
부모와 자식 간에 데이터를 주고받아야 한다.
Props와 State는 React에서 데이터를 관리하는 데에 필수적인 요소이므로,
확실하게 이해하여 사용하는 것이 중요하다 😶

State

state는 컴포넌트 자신이 가지고 있는 상태값이다.
함수 안에서 변수를 선언하면 그 변수는 함수 자신이 소유하고 관리하는 값이 되듯이, state는 화면에 보여줄 컴포넌트의 상태값을 가지고 있는 객체이다.
자신이 가지고 있는 값이기 때문에 컴포넌트 내부에서 직접 값을 변경할 수 있다.

class Parent extends React.Component {
  constructor() {
    super();
    this.state = {
      weather: 'HOT'
    };
  }
  
  render(){
    return <h1>Today's weather is {this.state.weather}!</h1>;
    // print: Today's weather is HOT!
  }
}

우선 this.state에서 초기값을 선언한다.
this.state는 객체이므로 key: value 형식으로 적어주면 된다.
컴포넌트 안에서 state 값을 가져올 때는 this.state.key값으로 불러올 수 있다.
this.state.key값을 value로 가지고 있는 엘리먼트는 state값에 따라 자신의 값이 결정되기 때문에, state값이 변경되면 함께 값이 변경될 것이다.
그럼, 선언된 state값은 어떻게 변경할 수 있을까?

class Parent extends React.Component {
  constructor() {
    super();
    this.state = {
      weather: 'HOT'
    };
  }
  
  handleWeather = () => {
    this.setState({
      weather: 'COLD'
    })
  }
  
  render(){
    return (
      <h1>Today's weather is {this.state.weather}!</h1>
      <button onClick={this.handleWeather}>Change Weather</button>
    );
    
  }
}

state값은 this.setState 함수에서 key의 value값을 다시 지정해주는 방식으로 변경할 수 있다. this.setState가 불려지는 시점에, 컴포넌트는 render 함수를 다시 실행한다. 변경된 state값을 대입하여 변경된 내용으로 다시 화면을 그려주는 것이다.

state 값을 부를 때 {this.state.~~~}, 함수를 부를 때 {this.함수명}
이렇게 계속 this 가 나오는 것을 볼 수 있다.
this는 '내가 소속된 이 컴포넌트'를 가리키는 것이라고 생각하면 쉽다.

Ex) Profile 컴포넌트에서 this.handleClick 함수의 this는,
Profile 컴포넌트 자신을 가리키는 것이다.

props

props는 부모 컴포넌트가 자식 컴포넌트에게 넘겨주는 속성으로,
모든 컴포넌트가 가지고 있는 내장 객체이다.
자신이 소유하고 있어서 값을 마음대로 바꿀 수 있는 state와는 달리,
props 부모 컴포넌트로부터 전달받았기 때문에 값을 변경할 수 없다.
props를 통해 부모 컴포넌트는 자식 컴포넌트에게 자신의 state값, event 등을 넘겨줄 수 있다.

// Main.js
import React from 'react';
import Comment from './Comment.js';

class Main extends React.Component {
  constructor() {
    super();
    this.state = {
      userID: 'Quokka'
    }
  }
  
  render() {
    return(
      <div>
        <h1>Comment List</h1>
        <ul>
      	  <Comment userID={this.state.userID}/>
        </ul>
      </div>
    );
  }
}

export default Main;

위의 코드를 보면 Main.js의 state값인 userID를 Comment 컴포넌트를 불러올 때 넘겨준다.

// Comment.js
import React from 'react';

class Comment extends React.Component {
  render() {
    console.log(this.props);
    // 
    return <li>I'm {this.props.userID}</li>
  }
}

export default Comment;

Main.js에서 넘겨준 userID를 Comment.js에서 받을 때 {this.props.userID}로 받는 것을 확인할 수 있다.
Comment.js에서 넘어온 props 값을 console.log(this.props)로 확인한 결과,
userID가 객체로 넘어왔음을 알 수 있다.

위와 같은 방식으로 부모 컴포넌트는 state값 뿐만 아니라 함수, 이벤트 등을 넘겨줄 수 있다.

구조 분해 할당

구조 분해 할당은 ES6가 등장하면서 사용된 방식이다.
객체와 배열에 담긴 값을 가져올 때, 객체나 배열을 변수로 분해함으로써
코드의 중복을 줄이고 간결하게 표현할 수 있다.

let arr = ['Poo', 'Robbin'];
let [first, second] = arr;
// first = 'Poo', second = 'Robbin' 

React로 개발을 하다 보면, this.props.~~~ this.state.~~~~ 가 계속 반복된다. 그냥 사용해도 상관은 없지만, 코드를 줄이거나 가독성을 높이고 싶다면 구조 분해 할당 방식을 사용해도 된다.

const isSwitchOn = this.state.isSwitchOn;
const color = this.state.color;

위 두 줄의 코드를

const {isSwitchOn, color} = this.state

이렇게 한 줄로 표현할 수 있다.

마무리

React를 사용하면서 어려운 점이 크게 두 가지 있었다.

  1. 원하는 element를 가져와서, 그 element에 직접 event나 함수를 부여하는
    Vanilla Js와는 달리, React는 컴포넌트에 event와 함수를 부여한다.
    기존 방식에서 벗어나서 컴포넌트 단위로 생각하는(?) 것이 꽤 어려웠다.

  2. 부모와 자식 간에 데이터를 어떻게 주고 받는가?
    어떤 타이밍에 부모와 자식간에 데이터 이동이 있어야 하고,
    내가 만들고자 하는 데이터/함수/로직은 어느 컴포넌트에 위치하는 것이 적절할까?

결론적으로 React를 많이 써봐야 코드를 짜는 것에 있어서 나만의 소신과 룰이 생기고, 그러면서 익숙해지는 것이라고 생각한다.
이번에 props와 state의 개념을 이해하고 나서 2번 고민에 대한 의문이 어느 정도 풀린 것 같다.
그래서인지 인스타그램 댓글 추가 기능도 데이터를 넘겨주는 부분에서 막혀 있었는데, 세션을 듣고 나서 바로 해결할 수 있었다 😁

profile
쿼카를 사랑하는 프론트엔드 개발자입니다 :)

0개의 댓글