Java Script/React

React 컴포넌트 알아보기

Zin0_0 2020. 11. 4. 00:05
반응형

컴포넌트

  • 컴포넌트의 기능은 단순한 템플릿 이상

  • 함수형 컴포넌트, 클래스형 컴포넌트

  • 클래스형 컴포넌트

    • import React, { Component } from 'react';
       
      class App extends Component {
        render() {
          const name = 'react';
          return <div className="react">{name}</div>;
        }
      }
       
      export default App;
    • 장점

      • state 기능 및 라이프사이클 기능을 사용할 수 있음
      • 임의 메서드를 정의할 수 있음
  • 함수형 컴포넌트

    • const MyComponent = () => {
        const name = 'zin0';
        return (
          <Fragment>
              {/* 주석 맞지? */}
              <p>
                반갑다 {name}
              </p>
          </Fragment>
        );
      }
      
      export default MyComponent;
    • 장점

      • 컴포넌트 선언이 훨씬 편함
      • 메모리 자원도 클래스형 컴포넌트보다 덜 사용
      • 프로젝트를 완성하여 빌드한 후 배포할 때도 함수형 컴포넌트를 사용하는 것이 결과물의 파일 크기가 더 작음(성능과 파일 크기 면에서 사실상 별 차이가 없으므로 이 부분은 너무 중요하게 여기지 않아도 됩니다).
    • 단점

      • state와 라이프사이클 API의 사용이 불가능
        • 리액트 v16.8 업데이트 이후 Hooks 기능이 도입되면서 해결됨
        • 컴포넌트를 새로 작성할 때 함수형 컴포넌트와 Hooks를 사용하도록 권장
  • props

    • properties의 준말로 컴포넌트 속성을 설정할 때 사용하는 요소

    • props는 해당 컴포넌트를 불러와서 사용하는 부모 컴포넌트에서 설정할 수 있음

    • const MyComponent = props => {
        return (
          <Fragment>
              {/* 주석 맞지? */}
              <p>
                반갑다 {props.name}
              </p>
          </Fragment>
        );
      }
    • const App = () => {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Hello, World.
              </p>
              <MyComponent name='zin0' />
            </header>
          </div>
        );
      }

       

    • default props

      • 자식 컴포넌트에 설정

      • const MyComponent = props => {
          return (
            <Fragment>
                {/* 주석 맞지? */}
                <p>
                  반갑다 {props.name}
                </p>
            </Fragment>
          );
        }
        
        MyComponent.defaultProps = {
            name : 'zin0!'
        }
      • const App = () => {
          return (
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                  Hello, World.
                </p>
                <MyComponent />
              </header>
            </div>
          );
        }
    • 태그 사이의 내용을 보여 주는 children

      • 부모 컴포넌트에서 자식 컴포넌트를 사용할 때, 태그 사이에 내용을 작성하여 보여주는 props

      • 자식 컴포넌트에서 작성

      • const MyComponent = props => {
          return (
            <Fragment>
                {/* 주석 맞지? */}
                <p>
                  반갑다 {props.name}
                </p>
                <p>
                  children 값 : {props.children}
                </p>
                
            </Fragment>
          );
        }
      • const App = () => {
          return (
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                  Hello, World.
                </p>
                <MyComponent name='zin0'>children test</MyComponent>
              </header>
            </div>
          );
        }
    • propTypes를 통한 props 검증

      • import PropTypes from ‘prop-types‘;

      • 자식 컴포넌트에서 작성 (props를 검증하기 때문)

      • MyComponent.propTypes = {
            name: PropTypes.string
        };
        
        // export 전에 어디든 추가
      • const App = () => {
          return (
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                  Hello, World.
                </p>
                <MyComponent name={3}>children test</MyComponent>
              </header>
            </div>
          );
        }
      • 개발자 도구를 확인해보면, string type이 들어와야하는데 number 타입이 들어왔다고 혼내고있음

    • isRequired를 사용하여 필수 propTypes 설정

      • const MyComponent = ({name,favoriteNumber, children}) => {
          return (
            <Fragment>
                {/* 주석 맞지? */}
                <p>
                  반갑다 {name} : {favoriteNumber}
                </p>
                <p>
                  children 값 : {children}
                </p>
                
            </Fragment>
          );
        }
        
        MyComponent.defaultProps = {
            name : 'zin0!'
        }
        
        MyComponent.propTypes = {
            name: PropTypes.string,
            favoriteNumber: PropTypes.number.isRequired
        };
      • 역시나 콘솔창을 보면, favoriteNumber 왜 입력 안했냐고 화내고있다.

      • const App = () => {
          return (
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                  Hello, World.
                </p>
                <MyComponent name='zin0' favoriteNumber={7}>children test</MyComponent>
              </header>
            </div>
          );
        }
      • 빠르게 추가해서 진정시켜주자.

  • 클래스형 컴포넌트에서 props 사용하기

    • import React, { Component } from ‘react‘;
      import PropTypes from ‘prop-types‘;
      
      class MyComponent extends Component {
        render() {
          const { name, favoriteNumber, children } = this.props; // 비구조화 할당
          return (
            <div>
              안녕하세요, 제 이름은 {name}입니다. <br />
              children 값은 {children}
              입니다.
              <br />
              제가 좋아하는 숫자는 {favoriteNumber}입니다.
            </div>
          );
        }
      }
      
      MyComponent.defaultProps = {
        name: ‘기본 이름‘
      };
      
      
      
      MyComponent.propTypes = {
        name: PropTypes.string,
        favoriteNumber: PropTypes.number.isRequired
      };
      
      export default MyComponent;
  •  
import React, { Component } from ‘react‘;
import PropTypes from ‘prop-types‘;

class MyComponent extends Component {
  render() {
    const { name, favoriteNumber, children } = this.props; // 비구조화 할당
    return (
      <div>
        안녕하세요, 제 이름은 {name}입니다. <br />
        children 값은 {children}
        입니다.
        <br />
        제가 좋아하는 숫자는 {favoriteNumber}입니다.
      </div>
    );
  }
}

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



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

export default MyComponent;
  • 위의 두 방법 모두 가능한데, 클래스의 특성과 가독성을 고려했을 때는 아래가 더 좋아보임
  • state

    • 컴포넌트 내부에서 바뀔 수 있는 값

      • cf.) props는 컴포넌트가 사용되는 과정에서, 부모 컴포넌트가 설정하는 값 (read, excute)
    • 클래스형 컴포넌트가 지니고 있는 state, 함수형 컴포넌트에서 useState 함수를 통한 state

    • 클래스형 컴포넌트의 state

      • import { Component } 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.increaseNum(number)}>
                        +1 시키기
                        </button>
                    </div>
                );
            }
            increaseNum(number) {
                this.setState({ number: number + 1 });
            }
        }   
        export default Counter;
      • 또한, 아래와 같은 형태로 생성자 없이 state를 만들 수 있음

      • import { Component } from "react";
        
        class Counter extends Component {
            state = {
                number: 0,
                fixedNum: 7
            }
            render() {
                const {number,fixedNum} = this.state;
                return (
                    <div>
                        <h1>Increasing : {number}</h1>
                        <h1>Fixed : {fixedNum}</h1>
                        <button onClick={() =>this.increaseNum(number)}>
                        +1 시키기
                        </button>
                    </div>
                );
            }
            increaseNum(number) {
                this.setState({ number: number + 1 });
            }
        }   
        export default Counter;

         

    • 함수형 컴포넌트에서 useState 사용하기

      • import React, { useState } from 'react';
        
        const SaySomething = () => {
            const [message, setMessage] = useState('');
            const onClickEnter = () => setMessage('어서 오고~');
            const onClickLeave = () => setMessage('멀리 안나감~');
        
            const [color, setColor] = useState('black');
            
            return (
                <div>
                    <button onClick={onClickEnter}>입장</button>
                    <button onClick={onClickLeave}>퇴장</button>
                    <h1>{message}</h1>
                    <h1 style={{ color }}>{message}</h1>
                    <button style={{ color: 'red' }} onClick={() => setColor('red')}>
                        빨간색
                    </button>
                    <button style={{ color: 'green' }} onClick={() => setColor('green')}>
                        초록색
                    </button>
                    <button style={{ color: 'blue' }} onClick={() => setColor('blue')}>
                        파란색
                    </button>
                </div>
            );
        };
        
        export default SaySomething;

         

    • 주의 사항

      • state 값을 바꿔야 할 때는 setState or useState를 통해 전달받은 세터 함수를 이용해야함

Reference

리액트를 다루는 기술

반응형