React Component 생성 및 props 정리

김영석·2022년 7월 9일

React

목록 보기
3/6

React는 다수의 컴포넌트를 만들고 그 컴포넌트들을 조합해서 하나의 웹페이지를 만든다. 이 과정에서 컴포넌트를 만드는 방법과 컴포넌트의 형태에 대한 내용과 부모, 자식 컴포넌트간 데이터를 전달하는 방법인 props에 대한 내용을 정리해보고자 한다.

1. 클래스형 컴포넌트

import {component} from 'react';

class App extends Component {
   render() {
      const name = "react"
      return <div className="react">{name}</div>;
   }
}

export default App;

클래스형 컴포넌트에서는 render 함수가 꼭 있어야 하고 그 안에 JSX를 반환해야 한다.
또한 state기능 및 라이프사이클 기능을 사용할 수 있다는 점과 임의 메서드를 정의 할 수 있다.

2.함수형 컴포넌트

import './App.css';

function App() {
   const name = 'react';
   return <div className="react">{name}</div>
}

export default App;

함수형 컴포넌트는 클래스형 컴포넌트 보다는 선언하기 간편하다. 또한 함수형 컴포넌트를 사용하는 것이 파일 크기 문제에서도 더욱 유리하다고 한다.

단점으로는 state와 라이프사이클 API를 사용하지 못한다는 것인데 이는 16.8 업데이트 이후에 Hooks라는 기능이 도입되면서 해결이 되었다고 한다.

리액트 공식 매뉴얼에서도 함수형 컴포넌트와 Hooks을 사용하라고 권장하고 있으니 익숙해지는것이 좋을 듯 하다.

3. 신규 컴포넌트 생성

일단 컴포넌트를 만들기 전에 프로젝트 src폴더 안에 components라는 폴더를 생성한 뒤 해당 폴더에 component를 생성한다.

그 다음 컴포넌트 파일을 생성 한 뒤 다음과 같이 컴포넌트를 만들어준다.

import React from "react";

const MyComponent = () => {
  return (
    <div>components</div>
  );
};

export default MyComponent;

함수형 컴포넌트는 화살표 함수로 생성할 수도 있다.

그 다음 만든 컴포넌트를 다음과 같이 불러와서 사용한다.

import React, { Component } from "react";
import MyComponent from "./components/MyComponent";

export default class App extends Component {
  render() {
    return (
      <div>
        <MyComponent></MyComponent>
      </div>
    );
  }
}

exfault default App;

4. props

props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위해 사용한다.

다음과 같이 데이터를 전달 할 수 있다.

App.js

import React, { Component } from "react";
import MyComponent from "./components/MyComponent";

export default class App extends Component {
  render() {
    return (
      <div>
        <MyComponent name="React"></MyComponent>
      </div>
    );
  }
}

exfault default App;

MyComponent.js

import React from "react";

const MyComponent = props => {
  return (
    <div>{props.name}</div>
  );
};

export default MyComponent;

부모 컴포넌트에서 받은 데이터를 렌더링 할 경우 {}로 감싸줘서 렌더링 할 수 있다.

또한 props에도 default값을 설정 할 수 있다.

import React from "react";

const MyComponent = props => {
  return (
    <div>{props.name}</div>
  );
};

MyComponent.defaultProps = {
   name:'기본 이름'
}

export default MyComponent;

그리고 컴포넌트 태그 사이에 내용이 들어가 있는 경우 이를 보여주고 싶을 때 children이라는 값을 보여주면 된다.

App.js

import React, { Component } from "react";
import MyComponent from "./components/MyComponent";

export default class App extends Component {
  render() {
    return (
      <div>
        <MyComponent name="React">리액트</MyComponent>
      </div>
    );
  }
}

exfault default App;

MyComponent.js

import React from "react";

const MyComponent = props => {
  return (
    <div>{props.name}</div>
    <div>{props.children}</div>
  );
};

MyComponent.defaultProps = {
   name:'기본 이름'
}

export default MyComponent;

props가 여러개인 경우 비구조화 할당 문법을 통해서 더 간결하게 코드를 작성할 수도 있다.

import React from "react";

const MyComponent = props => {
  const { name, children } = props;
  return (
    <div>{name}</div>
    <div>{children}</div>
  );
};

MyComponent.defaultProps = {
   name:'기본 이름'
}

export default MyComponent;

props의 타입을 지정하고 싶은 경우 다음과 같이 코드를 작성한다. isRequired를 통해 props를 전달하지 않을 시 경고 메시지를 띄울 수도 있다.

import PropTypes from 'prop-types';
import React from "react";

const MyComponent = props => {
  const { name, children, favoriteNumber } = props;
  return (
    <div>{name}</div>
    <div>{children}</div>
    <br/>
    <div>{favoriteNumber}</div>
  );
};

MyComponent.defaultProps = {
   name:'기본 이름'
}

MyComponent.propTypes = {
   name:PropTypes.string,
   favoriteNumber:PropTypes.number.isRequired
}
export default MyComponent;

클래스형 컴포넌트에서 props를 사용하고 싶은 경우 다음과 같이 코드를 작성한다.

import React from "react";
import { Component } from "react";

class MyClassComponent extends Component {
  render() {
    const { name, favoriteNumber, children } = this.props;
    return (
      <div>{name}</div>
      <div>{children}</div>
      <br/>
      <div>{favoriteNumber}</div>
    );
  }
}

export default MyClassComponent;

5. state

state란 리액트 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.

props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 속성이다. 따라서 props를 변경하고 싶으면 부모 컴포넌트에서 변경할 수 있고 자식 컴포넌트에서는 변경할 수 없다.

만약에 자식 컴포넌트에서 데이터를 변경하고 싶을 경우 state를 정의해서 사용해야 한다.

클래스 컴포넌트에서 state를 정의, 사용할 경우 다음과 같이 작성한다

import { Component } from "react";
import React from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { //초기값 설정
      number: 0,
    };
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
           onClick={() => {
              this.setState({number:number+1})
           }}
        >
        </button>
      </div>
    );
  }
}

export default Counter;

클래스형 컴포넌트에서는 state를 사용하기 위해 constructor 메서드를 작성해야 한다. 그리고 super(props)를 호출해야 한다.

state를 초기화 할 수도 있는데 this.state값에 초기화를 해준다 이때 state는 객체 형식이어야 한다.

render함수에서 state를 조회하기 위해서는 this.state를 조회하면 된다. 또한 state를 변경하고 싶다면 this.setState 함수를 사용해서 변경해준다.

만약 state를 변경한 뒤 특정 로직을 실행하고 싶다면 다음과 같이 setState 함수 두번째 파라미터로 콜백 함수를 등록한다.

import { Component } from "react";
import React from "react";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { //초기값 설정
      number: 0,
    };
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
           onClick={() => {
              this.setState({number:number+1},
              () => {
                 console.log("state 변경");
              })
           }}
        >
        </button>
      </div>
    );
  }
}

export default Counter;

함수형 컴포넌트에서는 다음과 같이 state를 사용한다

import React, { useState } from "react";

const CounterFuctionComponent = () => {
  const [message, setMessage] = useState("");
  const [color, setColor] = useState("black");
  const onClickEnter = () => {
    setMessage("환영합니다");
  };
  const onClickLeave = () => {
    setMessage("안녕히 가세요!");
  };
  return (
    <div>
      <button onClick={onClickEnter}>입장</button>
      <button onClick={onClickLeave}>퇴장</button>
      <h1 style={{ color }}>{message}</h1>
    </div>
  );
};

export default CounterFuctionComponent;
profile
아직 많이 부족한 개발자

0개의 댓글