데이터 관리 (Props와 State)
포스트
취소

데이터 관리 (Props와 State)

Props (Properties)

  • props는 자바스크립트 함수의 인자와 비슷한 개념이다.
  • HTML 태그의 속성 목록이 props가 된다.
  • props는 컴포넌트에 데이터를 전달하고자 할 때 사용한다.
  • 전달된 값은 변수를 통해 참조할 수 있다.
  • React에서 데이터의 흐름은 부모 컴포넌트로부터 자식 컴포넌트에게 전달된다.
    • props의 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.

props 설정하고 사용하기

  • React에서 props를 설정하는 방법은 HTML 요소에 속성을 설정하는 문법과 동일하다.
  • props의 이름은 해당 값이 사용될 환경의 맥락이 아닌 컴포넌트 자체의 관점에서 짓는 것이 권장된다.
  • 전달된 props의 사용법은 자바스크립트 함수에 인수를 전달하는 문법과 동일하다.
  • props는 객체 형태로 전달되기 때문에 props의 값을 참조하기 위해서는 자바스크립트의 속성 접근자(.)를 사용해야 한다.
  • 예시
/* Member.js */

const MemberInfo = (props) => {
  return <h1>이름 : {props.username}</h1>;
};

export default MemberInfo;
/* App.js */

const App = () => {
  return <MemberInfo username="홍길동"/>;
};

export default App;

props로 여러 데이터 전달하기

  • props로 여러 데이터를 전달하기 위해서는 해당 컴포넌트에 여러 개의 속성을 지정하면 된다.
  • 예시
/* Member.js */
const MemberInfo = (props) => {
  return (
      <>
        <h1>이름 : {props.username}</h1>
        <h1>나이 : {props.age}</h1>
      </>
    );
};

export default MemberInfo;
/* App.js */
const App = () => {
  return <MemberInfo username="홍길동" age="28"/>;
};

export default App;

구조 분해 할당(destructuring assignment)

  • 속성이 늘어날 수록 props.속성명이라고 명시하는 부분이 많아진다.
    • 이를 위해 ES6의 문법인 구조 분해 할당을 사용하기도 한다.
  • 예시
/* Member.js */

const MemberInfo = ({username, age}) => {
  return (
      <>
        <h1>이름 : {username}</h1>
        <h1>나이 : {age}</h1>
      </>
    );
};

export default MemberInfo;
/* App.js */

const App = () => {
  return <MemberInfo username="홍길동" age="28"/>;
};

export default App;

defaultProps로 기본값 설정하기

  • 부모 컴포넌트에서 props로 사용할 값을 넘기지 않으면 해당 부분은 공백으로 표시된다.
  • 위의 문제를 막기 위해 자식 컴포넌트에서 defaultProps로 기본값을 설정한다.
/* Member.js */

const MemberInfo = ({username, age}) => {
  return (
      <>
        <h1>이름 : {username}</h1>
        <h1>나이 : {age}</h1>
      </>
    );
};

MemberInfo.defaultProps = {
  username: "홍길동",
  age: "28"
};

export default MemberInfo;
/* App.js */

const App = () => {
  return <MemberInfo username="홍길동"/>;
};

export default App;

children으로 태그 사이의 내용 참조하기

  • React 컴포넌트의 시작 태그와 종료 태그 사이의 내용을 참조하고 싶다면 children이라는 props를 사용하면 된다.
    • 태그 사이의 내용이란 문자열, 자식 엘리먼트 등이 해당된다.
    • 이 때의 엘리먼트라는 것은 JSX의 엘리먼트를 의미한다.
    • 단순한 <div></div>같은 HTML 요소는 children의 length에 포함되지 않는다.
  • 예시
/* Member.js */

const MemberInfo = (props) => {
  return (
      <>
        <h1>{props.children}</h1>
        <h1>자식 엘리먼트의 갯수는 {props.children.length ?? 0}개입니다.</h1>
      </>
    );
};

export default MemberInfo;
/* App.js */

const App = () => {
  return (
    <>
      <MemberInfo username="홍길동">
        <div>아무 문자열</div>
      </MemberInfo>
    </>
  );
};

export default App;

props는 읽기 전용이다.

  • props는 부모 컴포넌트에서 그 값을 설정하므로, 자식 컴포넌트에서는 해당 props를 읽을 수 밖에 없다.
  • 만약 해당 props의 값을 변경하고 싶다면 부모 컴포넌트에서 그 값을 다시 설정해야 한다.
  • React에서는 모든 컴포넌트가 자신의 props를 다룰 때 반드시 순수 함수처럼 동작할 것을 요구한다.
    • 물론 실제 애플리케이션에서 UI는 언제나 동적으로 변화하기 때문에
      사용자의 입력, 네트워크 응답이나 다른 엘리먼트에 대한 응답에 따라 값을 수정해야 할 필요가 생길 수 있다.
    • React에서는 이러한 경우 상태(state)라는 개념을 사용하여 이 문제를 해결한다.
순수 함수
  • 함수 중에서 동일한 입력값에 대해 언제나 동일한 결과를 반환하는 함수
  • 예시
function Add(a, b) {
  return a + b;
}
비순수 함수
  • 동일한 입력값을 받아도 다른 변수나 메소드에 의해 같거나 다른 결과를 반환하는 함수
  • 예시
let c = 5;
function Add(a, b) {
  return a + b + c;
}

State

  • 컴포넌트가 가지고 있는 상태값
  • 함수 내에서 선언된 변수처럼 컴포넌트 내에서 관리된다.
  • React v16.8 이전까지는 함수 컴포넌트에서는 state를 사용할 수 없었다.
    • state를 사용하기 위해서는 어쩔 수 없이 클래스 컴포넌트를 사용해야 했었다.
  • React v16.8부터 도입된 useState Hook을 사용하면 함수 컴포넌트에서도 state를 사용할 수 있게 되었다.
    • 그래서 현업에서는 간결한 함수 컴포넌트를 많이 사용하게 되었다.

함수 컴포넌트의 State 변경하기

  • React Hooks 중에서 useState Hook을 통해서 State를 변경한다.
  • 참고

클래스 컴포넌트의 State 변경하기

  • 클래스 컴포넌트가 상속받고 있는 Component는 상태를 변경하는 setState라는 메소드가 존재한다.
  • 예시 (흔한 예제인 카운터 컴포넌트)
/* Counter.js */

import React from 'react';

class Counter extends React.Component {
    state = {
      number: 0,
    };
    calc = (val) => {
        this.setState({ number: this.state.number + val });
    }
    render() {
      const { number } = this.state;
        
      return (
        <div>
          <h1>{number}</h1>
          <button onClick={() => { this.calc(-1); }}>-1</button>
          <button onClick={() => { this.calc(1); }}>+1</button>
        </div>
      );
    }
  }
  
  export default Counter;
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.