반응형

React Component에서 다루는 데이터는 props와 state

 

props

자식 Component가 생성될 때 부모 Component에서 받아온 데이터로 변경이 불가능

자식 Component에서 this라는 키워드를 통해 부모 Component로부터 받은 props를 사용할 수 있음

 

src/Card.js

// Card.js
import React, { Component } from "react";
 
class Card extends Component {
  render() {
    return (
      <React.Fragment>
        <h3>
          이름 : <b>{this.props.name}</b>
        </h3>
        <h3>
          소속 : <b>{this.props.department}</b>
        </h3>
        <h3>
          연락처 : <b>{this.props.phone}</b>
        </h3>
        <h3>
          이메일 : <b>{this.props.email}</b>
        </h3>
      </React.Fragment>
    );
  }
}
 
export default Card;

scr/App.js 수정

// App.js
import React, { Component } from "react";
import Card from "./Card";
 
class App extends Component {
  render() {
    return (
      <Card
        name="jisu"
        department="Dev"
        phone="010-1234-5678"
        email="282532@naver.com"
      />
    );
  }
}
 
export default App;

Card가 App의 자식 Component가 되는 것
이 때, 부모Component(App.js) 에서 지정한 name, department, phone, email

-> 자식Component(Card.js)로 전달되어 

Card에서 this.props.name, this.props.department, this.props.phone, this.props.email이 사용

 

<defaultProps>

- 부모 Component 가 여러 개의 공통된 자식 Component 를 사용할 경우

 -> 하지만, 자식 Component에서 공통적으로 사용되는 props와 값이 다양한 props가 있을 수 있다

- 이 경우 , 자식 Component에서 defaultPorps를 이용하여 props의 기본값을 설정해 줄 수 있음

- 기본값 : 부모 Component에서 지정해 줄 경우 지정한 값으로 지정하지 않으면 기본값으로 props가 적용

 

//Card.js

import React, { Component } from "react";
 
class Card extends Component {
  static defaultProps = {
    department : "Dev"
  };

  render() {
    return (
      <React.Fragment>
        <h3>
          이름 : <b>{this.props.name}</b>
        </h3>
        <h3>
          소속 : <b>{this.props.department}</b>
        </h3>
        <h3>
          연락처 : <b>{this.props.phone}</b>
        </h3>
        <h3>
          이메일 : <b>{this.props.email}</b>
        </h3>
      </React.Fragment>
    );
  }
}
 
export default Card;

//App.js

// App.js
import React, { Component } from "react";
import Card from "./Card";
 
class App extends Component {
  render() {
    return (
      <React.Fragment>
        {/* department 생략 */}
        <Card name="jisu" phone="010-1234-5678" email="282532@naver.com" />
        <hr />
        {/* department 포함 */}
        <Card
          name="joby"
          department="Marketing"
          phone="010-5678-9123"
          email="bob@bob.com"
        />
      </React.Fragment>
    );
  }
}
 
export default App;

<Functional Component(함수형 컴포넌트)>

- 클래스형 컴포넌트 외 다른 방법으로 컴포넌트 생성

- 단순히 props 받아오는 컴포넌트의 경우 더 간단한 문법으로 사용 가능

- 함수형 컴포넌트는 컴포넌트가 함수이기 때문에 클래스의 특성에서 지닐수 있는 static이나 this 키워드를 사용할 수 없음

-  state나 Life Cycle과 관련된 함수를 사용할 수 없습니다.

 

//Card.js => 함수의 매개변수로 props의 인자들 직접 받음 

 

// Card.js
import React from "react";
 
const Card = ({ name, department, phone, email }) => {
  return (
    <React.Fragment>
      <h3>
        이름 : <b>{name}</b>
      </h3>
      <h3>
        소속 : <b>{department}</b>
      </h3>
      <h3>
        연락처 : <b>{phone}</b>
      </h3>
      <h3>
        이메일 : <b>{email}</b>
      </h3>
    </React.Fragment>
  );
};
 
// 기본 props 지정(함수형 컴포넌트 사용시 static을 사용불가)
Card.defaultProps = {
  department: "Dev"
};
 
export default Card;

state

-  Component 내부에서 생성된 데이터로 변경이 가능

- Component 내부에 state를 class field나 constructor(props) 내부에 정의해서 사용

 

Method Binding

- 이벤트 처리할 경우 , 임의의 메소드 생성

- 이 때, 해당 메소드에서 state를 변경하기 위해 this 키워드를 사용하려면 메소드에 this를 바인딩 시켜주어야

- constructor(props) 내부에 "this.메소드명 = this.메소드명.bind(this)"를 사용하여 메소드에 this를 바인딩

=> 이 작업이 없을 경우, 이벤트가 발생 시 해당 메소드가 이벤트로 전달되는 과정에서 this와 연결이 끊어져, undefined가 됨

      하지만, this 를 메소드로 화살표 함수 표현(Arrow Function Expression)으로 만들 경우,
      this 가 풀리는 것에 대해 걱정할 필요가 없기에 method binding 명시적으로 하지 않아도 됨

 

 

setState

- 선언된 state 값을 변경하기 위해서는 무조건 this.setState를 사용 /
   React 내부에서 setState를 호출하게 되면 자동으로 Component를 리렌더링하게 설계

- 객체로 전달되는 해당 값만 state에서 변경. 전달되지 않은 값은 기존값으로 유지.
   state 내부에 객체가 존재하고 그 객체의 특정 인자만 변경하고 싶다면
  "객체1: { ..., this.state.객체1, 변경요소: 변경요소 값 }"의 다음과 같은 구조로 작성

   =>  그렇지 않으면 객체 자체를 새로 덮어 써버림

 

 전개 연산자(Spread Operator, ...)을 사용하면 기존 내용을 해당 객체에 풀어줌.

 - 이 부분은 객체의 depth가 깊어지면 상당히 복잡해지므로 immutable.js나 immer.js를 이용해서 간단화 작업을 하는게 좋음

 - 기존의 값을 토대로 새로운 값으로 변경하고 싶을 땐 "값1: this.state.값1" 이런 식으로 처리.

     =>  this.state를 사용하고 싶지않다면 setState를 화살표 함수로 만들어서 매개변수로 state나 해당 값을 넣어주면 됨.

    이 때, 해당 값을 이용할 땐 비구조화 할당(Destructuring Assignment)이라는 문법을 사용합니다.

 - render() 함수 내부의 HTML 코드에서 이벤트를 설정할 땐, camelCase로 이벤트명을 적어야 함

  - 또한 이벤트 속성의 값으로는 "함수()" 형태가 아닌 "함수명"으로

     => 그렇지 않을 경우 함수 호출이 무한 루프에 빠질수 있습니다. (렌더링 -> 함수 호출 -> setState -> 리렌더링 -> 함수 호출 -> ...)

 

src/StopWatch.js

// StopWatch.js
import React, { Component } from "react";
 
class StopWatch extends Component {
  // class fields
  state = {
    sec: 0,
    buttonFlag: true,
    intervalFunction: null
  };
 
  // stop watch 로직
  timer = () => {
    // 비구조화 할당 사용( { sec } 부분 )
    this.setState(({ sec }) => ({
      sec: sec + 1
    }));
  };
 
  // start 버튼 클릭
  start = () => {
    this.setState({
      sec: 0,
      buttonFlag: false,
      intervalFunction: setInterval(this.timer, 1000)
    });
  };
 
  // stop 버튼 클릭
  stop = () => {
    clearInterval(this.state.intervalFunction);
 
    this.setState({
      buttonFlag: true
    });
  };
 
  render() {
    return (
      <React.Fragment>
        <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>
      </React.Fragment>
    );
  }
}
 
export default StopWatch;

src/App.js

// App.js
import React, { Component } from "react";
import StopWatch from "./StopWatch";
 
class App extends Component {
  render() {
    return <StopWatch />;
  }
}
 
export default App;

 

반응형

'Language Study > React' 카테고리의 다른 글

4. Life Cycle API  (0) 2019.11.26
2. JSX  (0) 2019.11.26
1. 준비사항  (0) 2019.11.26

+ Recent posts