개인 학습 - 리액트의 기본-2

44523·2023년 2월 11일

props 와 state

props는 부모 컴포넌트가 자식 컴포넌트에게 주는 값이다.
자식 컴포넌트에서는 props를 받아오기만 하고 직접 수정할 수 없다.

새로운 컴포넌트를 만들어 보자.

import React, { Component } from 'react';

class MyName extends Component {
  render() {
    return (
      <div>
        제 이름은 <b>{this.props.name}</b> 입니다.
      </div>
    );
  }
}

export default MyName;

받아온 props 값은 this. 키워드를 통해서 조회할 수 있다.

App.js를 통해 열어보면

import React, { Component } from 'react';
import MyName from './MyName';

class App extends Component {
  render() {
    return (
      <MyName name="리액트" />
    );
  }
}

export default App;

태그의 속성을 설정하듯이 적는다.

실수로 props를 빼먹거나 특정 상황에서 일부러 props 값을 비울때는 defaulProps를 사용한다.

import React, { Component } from 'react';

class MyName extends Component {
  static defaultProps = {
    name: '기본값 이름'
  }
  render() {
    return (
      <div>
        제 이름은 <b>{this.props.name}</b> 입니다.
      </div>
    );
  }
}

export default MyName;

이렇게 name값을 생략했을때 "기본값 이름"이 나타난다.
또한 defalutProps는 다음과 같은 형태로도 설정할 수 있다.

import React, { Component } from 'react';

class MyName extends Component {
  render() {
    return (
      <div>
        제 이름은 <b>{this.props.name}</b> 입니다.
      </div>
    );
  }
}

MyName.defaultProps = {
  name: '기본값 이름'
};

export default MyName;

함수형 컴포넌트

MyName 컴포넌트를 함수형 컴포넌트를 통해서 간편한 문법으로 작성해보자.

import React from 'react';

const MyName = ({ name }) => {
  return (
    <div>
      안녕하세요! 제 이름은 {name} 입니다.
    </div>
  );
};

export default MyName;

state

동적인 데이터를 다룰때는 state를 사용한다. 상태가 변하는 값을 넣는다고 생각하면 된다.
Counter라는 파일을 생성해서 입력한다.

import React, { Component } from 'react';

class Counter extends Component {
  state = {
    number: 0
  }

  handleIncrease = () => {
    this.setState({
      number: this.state.number + 1
    });
  }

  handleDecrease = () => {
    this.setState({
      number: this.state.number - 1
    });
  }

  render() {
    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.state.number}</div>
        <button onClick={this.handleIncrease}>+</button>
        <button onClick={this.handleDecrease}>-</button>
      </div>
    );
  }
}

export default Counter;

메소드를 작성한 부분이다.
this와의 연결이 끊겨버리지 않게 화살표함수 형태로 작성해준다.

handleIncrease = () => {
    this.setState({
      number: this.state.number + 1
    });
  }

  handleDecrease = () => {
    this.setState({
      number: this.state.number - 1
    });
  }

setState

state에 있는 값을 바꾸기 위해서는 this.setState를 거쳐야한다. 리액트에서는 이 함수가 호출되면 컴포넌트가 리렌더링 되도록 설계되어있다.

setState는 객체로 전달되는 값만 업데이트 해준다.
foo값을 추가로 작성하여

state = {
    number: 0,
    foo: 'bar'
  }

this.setState({ number: 1 }); 을 하게 되면 foo 는 그대로, number 값만 업데이트 된다.

또한 setState는 객체의 깊숙한 곳까지 확인하지 못한다.
state에 다음과 같이 값을 추가로 작성하고

state = {
    number: 0,
    foo: {
      bar: 0,
      foobar: 1
    }
  }

이 값이 업데이트 되었는지 확인해보면

this.setState({
  foo: {
    foobar: 2
  }
})

기존의 foo 객체가 바뀌어버린다.

{
  number: 0,
  foo: {
    foobar: 2
  }
}

위 상황에서는 이런식으로 작성해야 한다.

this.setState({
  number: 0,
  foo: {
    ...this.state.foo,
    foobar: 2
  }
});

...는 자바스크립트의 전개연산자로 기존 객체안에 있는 내용을 해당 위치에 풀어준다. 그리고 우리가 설정하고 싶은 값을 또 넣어주면 해당 값을 덮어쓰게 된다.

setState에 함수 전달하기

기존의 코드에서

this.setState({
  number: this.state.number + 1
});

구조분해 할당을 이용하여

this.setState(
  (state) => ({
    number: state.number
  })
);
this.setState(
  ({ number }) => ({
    number: number + 1
  })
);

이렇게 작성할 수 있다.

const { number } = this.state;
this.setState({
  number: number + 1
})

이런식으로도 작성 가능하다.

기존의 함수를 각각 다른방식으로 구현한다면

 handleIncrease = () => {
    const { number } = this.state;
    this.setState({
      number: number + 1
    });
  }

  handleDecrease = () => {
    this.setState(
      ({ number }) => ({
        number: number - 1
      })
    );
  }

이벤트 설정

render 함수에서 이벤트 설정한 부분

render() {
    return (
      <div>
        <h1>카운터</h1>
        <div>값: {this.state.number}</div>
        <button onClick={this.handleIncrease}>+</button>
        <button onClick={this.handleDecrease}>-</button>
      </div>
    );
  }

기존 자바스크립트로 작업한 것과 비교해보자.

<button onclick="alert('hello');">Click Me</button>
<button onClick={this.handleIncrease}>+</button>

이 둘의 차이는 리액트는 이벤트 이름이 카멜케이스라는 것이며 이번트에 전달해주는 값이 함수라는 것이다.
리액트에서 이벤트 함수를 설정할때는 꼭 지켜야할 사항들이다.
카멜케이스 예시 : onClick, onChange, 등등...

0개의 댓글