본문 바로가기
Front-End/React

[리액트를 다루는 기술] Component (props,state)

by Cafe Mocha 2022. 4. 27.

리액트를 다루는 기술 내용 정리

3장 컴포턴트

  • 함수형 컴포넌트의 장점메모리 자원을 덜 사용한다.
  • 최종 결과물의 파일 크기가 더 작다.(단, 성능, 파일크기 면에서 사실상 큰 차이가 없어 중요하게 생각하지 않아도 괜찮다)
  • 클래스형 컴포넌트 보다 선언하기가 편하다.
  • 함수형 컴포넌트의 단점
  • state와 라이프사이클 API를 사용할 수 없다.(리액트 v16.8 업데이트 Hooks의 기능으로 해결)

초기에는 클래스형 컴포넌트를 통해 리액트의 기본기를 익히고 Hooks를 이해한 후 함수형 컴포넌트로 사용.

  • ES6 화살표 함수주로 함수를 파라미터로 전달할 때 유용하다.
  • setTimeout(function() { console.log('hello world'); }, 1000); setTimeout(()=> { console.log('hello world'); }, 1000);
  • 화살표 함수는 ES6 문법에서 함수를 표현하는 새로운 방식

위 문법이 기존 function을 대체할 수 없는 이유는 용도가 다르기 때문이다.

서로 가리키고 있는 this 값이 다르다!

function BlackDog(){
	this.name = '흰둥이';
	return {
		name:'검둥이',
		bark: function(){
			console.log(this.name + ':멍멍!');
		}
	}
}

const blackDog = new BlackDog();
blackDog.bark(); // 검둥이: 멍멍!

function WhiteDog(){
	this.name = '흰둥이';
	return {
		name:'검둥이',
		bark: ()=>{
			console.log(this.name + ':멍멍!');
		}
	}
}

const whiteDog = new WhiteDog();
whiteDog.bark(); // 흰둥이: 멍멍!

function을 사용했을 때는 검둥이가 나타나고 화살표 함수를 사용할 때는 흰둥이가 나타난다.

일반 함수는 자신이 종속된 객체를 this로 가리키며, 화살표 함수는 자신이 종속된 인스턴스를 가리킨다.

  • props 전달
    • defaultProps
    • props 값을 따로 지정하지 않았을 때 보여줄 기본값 설정
    • children
      // App.js
      import "./App.css";
      import MyComponent from "./MyComponent";
      
      function App() {
        const name = "React";
        return <MyComponent>리액트</MyComponent>;
      }
      
      export default App;
      
      // MyComponent
      import React from "react";
      
      const MyComponent = (props) => {
        return (
          <div>
            안녕하세요, 제 이름은 {props.name}입니다. <br />
            children 값은 {props.children}
            입니다.
          </div>
        );
      };
      
      MyComponent.defaultProps = {
        name: "기본",
      };
      
      export default MyComponent;
      
    • 태그 사이의 내용을 보여주는 props
    • 비구조화 할당 문법을 통해 props 내부 값 추출하기
    • import React from "react"; const MyComponent = ({name, children}) => { return ( <div> 안녕하세요, 제 이름은 {name}입니다. <br /> children 값은 {children} 입니다. </div> ); }; MyComponent.defaultProps = { name: "기본", }; export default MyComponent;
    • propTypes를 통한 props 검증
      import PropTypes from "prop-types";
      
      ...
      
      MyComponent.propTypes = {
        name: PropTypes.string,
      };
      
    • 컴포넌트의 필수 props를 지정하거나, props의 타입을 지정할 때는 propTypes를 사용
    • isRequired를 사용하여 필수 propTypes 설정
      import PropTypes from "prop-types";
      
      ...
      
      MyComponent.propTypes = {
        name: PropTypes.string.isRequired,
      };
      
    • propTypes를 지정하지 않았을 때 경고 메시지를 띄워 주는 작업 → propTypes를 지정할 때 뒤에 isRequired를 붙여주면 된다.
  • 기본 전달 방법은 생략
  • state
    • 클래스형 컴포넌트의 state클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)를 호출해 주어야 한다.
      render() {
          const { number } = this.state;
          return (
            <div>
              <h1>{number}</h1>
              <button
                onClick={() => {
                  this.setState({ number: number + 1 });
                }}
              >
                +1
              </button>
            </div>
          );
        }
      }
      
      render 함수에서 현재 state를 조회할 때는 this.state를 조회한다.
      • state를 constructor에서 꺼내기
      //이전
      class Counter extends Component {
        constructor(props) {
          super(props);
          this.state = {
            number: 0,
            fixedNumber: 0,
          };
        }
      
      //이후
      class Counter extends Component {
        state = {
          number: 0,
          fixedNumber: 0,
        };
      
    • 이 함수가 호출되면 현재 클래스형 컴포턴트가 상속받고 있는 리액트의 Component 클래스가 지닌 생상자 함수를 호출한다.
    • //클래스형 컴포넌트의 state는 constructor 메서드를 작성해 설정 constructor(props) { super(props); // state의 초기값 설정하기 this.state = { number:0 }; }
    • this.setState에 객체 대신 함수 인자 전달하기
    				<button
              onClick={() => {
                this.setState((prevState) => ({
                  number: prevState.number + 1,
                }));
              }}
            >
              +1
            </button>
    
    • this.setState가 끝난 후 특정 작업 실행setState의 두 번째 파라미터로 콜백(callback) 함수를 등록
    • <button onClick={() => { this.setState( { number: number + 1, }, () => { console.log("방금 setState가 호출되었습니다."); } ); }} > +1 </button>
    • 함수 컴포넌트현재는 useState라는 함수를 사용해 함수 컴포넌트에서도 state를 사용할 수 있다.
      • useState
      • import React, { useState } from "react"; const Say = () => { const [message, setMessage] = useState(""); const onClickEnter = () => setMessage("안녕하세요!"); const onClickLeave = () => setMessage("안녕히 가세요!"); return ( <div> <button onClick={onClickEnter}>입장</button> <button onClick={onClickLeave}>퇴장</button> <h1>{message}</h1> </div> ); }; export default Say;
    • 리액트 16.8 이전 버전에서는 함수 컴포넌트에서 state를 사용할 수 없었다.
  • state를 사용할 때 주의사항리액트 불변성 → 추후 자세한 내용
  • 클래스형 컴포넌트든 함수 컴포넌트든 state값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달 받은 세터 함수를 사용해야 한다!

출처 : 리액트를 다루는 기술(김민준 님)