Components, props와 State

Lucy·2023년 3월 14일
0

React

목록 보기
4/7

Components

화면을 이루는 '요소'로 여러 곳에서 재사용 가능한 UI 코드 조각

React를 사용할 때 Component는 class나 function으로 정의할 수 있다.

  • Component의 이름은 항상 대문자로 시작한다.

  • 코드의 재사용성과 유지보수성을 증가시켜 준다.

  • 데이터의 단방향성

    • 데이터는 아래로 흐른다.
    • 부모 Component는 자식 Component가 어떤 상태인지 알 수 없고 관심을 가지지 않는다.
    • state가 소유하고 설정한 Component 이외에는 어떠한 Component에서도 접근할 수 없다.
    • Component가 자신의 state를 자식 Component에 props로 전달할 수 있다.

Component와 Props

Props

속성을 나타내는 데이터로 Property의 준말

  • 부모 Component에서 자식 Component로 전달해 준 데이터

Props를 개체로 받는 Component의 예시는 다음과 같다.

Ex. Class Component

import React from 'react'
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Ex. Function Component

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

props는 읽기 전용이다.

따라서 Component에서 자체 props를 수정할 수 없다.
즉, 모든 React Component는 자신의 props를 다룰 때 반드시 자신의 입력값을 바꾸지 않는 순수 함수처럼 동작해야 한다.

Component Rendering

React Element는 DOM 태그와 사용자 정의 Component 모두로 나타낼 수 있다.
React가 사용자 정의 Component로 작성한 Element를 발견하면 JSX 속성과 자식을 해당 Component에 단일 객체로 전달하는데, 이를 Props라 한다.

Ex.

const element = <Welcome name="Sara" />;

Component 합성 / 추출

Component는 자신의 출력에 다른 Component를 참조할 수 있다.

Ex.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

또한 Component를 여러 개의 작은 Component로 나눌 수 있다.

State

한 Component 내에서 완전히 제어되는 상태 (local/캡슐화) 를 나타내고 동적인 데이터를 다룰 때 사용

  • constructor가 아니라면 직접 State를 수정하지 않고 대신 setState()를 사용한다.
    직접 state를 수정하는 경우, component가 다시 렌더링되지 않는다.

    ```
    // Wrong
    this.state.comment = 'Hello';
    // Correct
    this.setState({comment: 'Hello'});
    ```
  • state 업데이트는 비동기적일 수 있으므로 객체보다는 함수를 인자로 사용하는 형태의 setState()를 사용하자.

    	```
    	// Wrong
    	this.setState({
    	counter: this.state.counter + 	this.props.increment,
    	});
    	// Correct
    	this.setState((state, props) => ({
    	counter: state.counter + props.increment
    	}));
    	```
  • state 업데이트는 병합된다. 즉, setState()를 호출할 때, React는 제공한 객체를 현재 state로 병합한다. 따라서 여러 번의 setState() 호출로 여러 변수를 독립적으로 업데이트할 수 있다.

- Hook의 useState로 상태를 추가해줄 수도 있다.

생명 주기와 생명 주기 메서드

Mount

Component의 instance가 생성되어 DOM 상에 삽입될 때 다음 메서드들이 순서대로 호출된다.

  1. constructor()
    • instance에 이벤트 처리 메서드를 바인딩하거나 state를 초기화하는 작업이 없다면, 해당 React Component에서는 constructor를 구현하지 않아도 된다.
    • 구현하는 경우, props를 기본 constructor로 호출해야 한다.
    • constructor() 내부에서 setState()를 호출하면 안된다. component에 지역 state가 필요하다면 constructor 내에서 this.state에 초기 state 값을 할당하면 된다. 다만 여기서도 state에 props를 복사하면 안 된다.
    constructor(props) {
    	super(props);
    	// 여기서 this.setState()를 호출하면 안 됩니다!
    	this.state = { counter: 0 };
    	this.handleClick = this.handleClick.bind(this);
    }
  2. static getDerivedStateFromProps()
  3. render()
    • Class component 내에서 반드시 구현되어야 하는 유일한 메서드
    • component의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환해야하며, 브라우저와 직접적으로 상호작용하지 않는다.
  4. componentDidMount()
    • component가 mount된 직후 (트리에 삽입된 직후)에 호출
    • 브라우저와 상호작용하는 작업이 필요할 때 사용

업데이트

props나 state가 변경되면 업데이트가 발생한다.
이 때 component가 다시 렌더링되면서 다음 메서드들이 순서대로 호출된다.

  1. static getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

Unmount

component가 DOM 상에서 제거될 때 호출된다.

  • componentWillUnmount()

오류 처리

자식 컴포넌트를 렌더링하거나, 자식 컴포넌트가 생명주기 메서드를 호출하거나, 또는 자식 컴포넌트가 생성자 메서드를 호출하는 과정에서 오류가 발생했을 때 호출된다.

  • static getDerivedStateFromError()
  • componentDidCatch()

State와 생명주기 사용 예시

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>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);

Ref

https://ko.reactjs.org/docs/react-component.html

https://ko.reactjs.org/docs/components-and-props.html

https://ko.reactjs.org/docs/state-and-lifecycle.html

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

profile
나아가는 OnlyOne 개발자

0개의 댓글