[React] State & Lifecycle

cptkuk91·2021년 12월 8일
0

React

목록 보기
2/5
post-thumbnail

출처: https://ko.reactjs.org/docs/handling-events.html!

Component를 완전히 재사용하고 캡슐화하는 방법을 알아야 합니다.

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

위 코드와 아래 코드의 차이는 function tick과 Clock에 차이가 있습니다.
ReactDOM.render 부분에 element 대신 Clock Component를 가져오면서 구현하였습니다.

State는 props와 유사하지만, 비공개이며 컴포넌트에의해 제어됩니다.

function에서 class로 변환하기

  • React.Component를 확장합니다.
  • render() 라고 불리는 빈 메서드를 추가합니다.
  • 함수의 내용을 render() 메서드 안으로 옮긴다.
  • render() 내용 안에 있는 props를 this.props로 변경
  • 남아있는 빈 함수 선언을 삭제
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

this.props.date를 통해 Clock date에 전달..

render 메서드는 업데이트가 발생할 때마다 호출되지만, 같은 DOM 노드로 Clock을 렌더링하는 경우 Clock 클래스의 단일 인스턴스만 사용됩니다. 이것은 로컬 state와 생명주기 메서드와 같은 부가적인 기능을 사용할 수 있게 해줍니다.


class에 로컬 state 추가하기

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

기존 render 안에 있는 this.props.date를 this.state.date로 변경합니다.
이후 this.state를 지정하는 class constructor를 추가합니다.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

더 깔끔하게 정리할 수 있습니다.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

LifeCycle

DOM이 렌더링 될 때마다 설정하는 것을 마운팅이라고 합니다. 반대로 DOM이 삭제될 때마다 해제하는 것을 언마운팅이라고 합니다.

이러한 메서드를 생명주기 메서드라고 합니다.


State 바르게 사용하기

setState()를 사용하기 전 반드시 알아야 할 3가지

// Wrong
this.state.comment = 'Hello';

// Correct
this.setState({comment: 'Hello'});

우선 기본적인 사용법입니다. (this.state를 지정할 수 있는 공간은 contructor 뿐입니다.)

state 업데이트는 비동기적일 수 있습니다.

React는 성능을 위해 여러 setState() 호출을 단일 업데이트로 한 번에 처리할 수 있습니다.

this.props와 this.state가 비동기적으로 업데이트 될 수 있기 때문에 다음 state를 계산할 때 해당 값에 의존해서는 안됩니다.

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

state 업데이트는 병합됩니다.

setState()를 호출할 때 React는 제공한 객체를 현재 state로 병합합니다.

  constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

데이터는 아래로 흐른다.

부모 컴포넌트나 자식 컴포넌트 모두 특정 컴포넌트가 유상태인지 또는 무상태인지 알 수 없고, 그들이 함수나 클래스로 정의되었는지에 대해서 관심을 가질 필요가 없습니다.

state가 소유하고 설정한 컴포넌트 이외에는 어떤 컴포넌트에도 접근할 수 없습니다.

컴포넌트는 자신의 state를 자식 컴포넌트에 props로 전달할 수 있습니다.

<FormattedDate date={this.state.date} />

위와 같은 경우에는 FormattedDate 컴포넌트는 date를 자신의 props로 받을 것이고 이것이 Clock의 state로부터 왔는지 props에서 왔는지 수동으로 입력했는지 알지 못합니다.

function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <FormattedDate date={this.state.date} />
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

일반적으로 이를 "하향식(top-down)" 또는 "단방향식" 데이터 흐름이라고 합니다. 모든 state는 항상 특정한 컴포넌트가 소유하고 있으며 그 state로부터 파생된 UI 또는 데이터는 오직 트리구조에서 자신의 "아래"에 있는 컴포넌트에만 영향을 미칩니다.

profile
메일은 매일 확인하고 있습니다. 궁금하신 부분이나 틀린 부분에 대한 지적사항이 있으시다면 언제든 편하게 연락 부탁드려요 :)

0개의 댓글