[React]리액트를 다루는 기술-3. 컴포넌트

chaaerim·2021년 11월 14일
0
post-thumbnail

오늘은 컴포넌트에 대해서 배워보자 !!

📖 컴포넌트

컴포넌트의 기능은 단순한 템플릿 이상이다.
데이터가 주어졌을 때 이에 맞춰 UI를 만들어주고, 라이프사이클 API를 이용하여 컴포넌트가 화면에서 변화가 일어날 때 주어진 작업들을 처리할 수 있으며, 임의 메서드를 만들어 특별한 기능을 붙여줄 수 있다.
컴포넌트를 선언하는 방식으로는 함수 컴포넌트클래스형 컴포넌트가 있다.

3.1. 클래스형 컴포넌트

✍ example

import {Component} from 'react';
import './App.css';

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

export default App;
클래스형 컴포넌트함수 컴포넌트
- state 기능 및 라이프 사이클 기능을 사용할 수 있음.- state와 라이프 사이클 API의 사용이 불가능.
- 임의 메서드를 정의할 수 있음.- 그러나 Hooks가 도입되면서 단점 해결.
- render함수가 꼭 있어야 하며, 이 안에서 보여줄 JSX를 반환해야 함.- 클래스형 컴포넌트보다 선언하기가 편하고 메모리 자원도 덜 사용함.

🧐 리액트 개발 팀에서는 함수 컴포넌트와 Hooks를 사용하는 것을 권장하고 있음!


3.2. 첫 컴포넌트 생성

파일 만들기 ➡ 코드 작성하기 ➡ 모듈 내보내기 및 불러오기

const MyComponent=()=>{
    return <div>자유로운 우리를 봐 자유로워</div>;
};
export default MyComponent;
  • 함수 코드를 작성할 때 function 키워드를 사용하는 대신 ES6에 도입된 화살표 함수 문법 을 사용.

ES6 화살표 함수

ES6 문법에서 함수를 표현하는 새로운 방식이다. 이 문법은 주로 함수를 파라미터로 전달할 때 유용하다.
✍ example

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.nane+'멍멍');
        }
    }
}
const whiteDog=new WhiteDog();
whiteDog.bark();
  • blackDog.bark();은 '검둥이: 멍멍'이 출력됨.
  • whiteDog.bark();은 '흰동이: 멍멍'이 출력됨.
  • 이는 서로 가리키고 있는 this의 값이 다르기 때문.
일반 함수화살표 함수
- 자신이 종속된 객체를 this로 가리킴- 자신이 종속된 인스턴스를 가리킴
-값을 연산하여 바로 반환해야 할 때 사용하면 가독성을 높일 수 있음.
- Ex) const triple =(value) => value*3;

3.3. props

props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다. props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.

3.3.1. JSX 내부에서 props 렌더링

✍ example

const MyComponent=props=>{
    return <div>안녕하세요 제 이름은 {props.name}입니다. </div>;
};
export default MyComponent;
  • props 값은 컴포넌트 함수의 파라미터로 받아와서 사용 가능.
  • props를 렌더링 할 때에는 { } 기호로 감싸주면 됨.

3.3.2. 컴포넌트를 사용할 때 props 값 지정하기

✍ example

import MyComponent from './MyComponent';

const App=()=>{
  return <MyComponent name='react'/>;
};

export default App;
  • 부모 컴포넌트에서 props 값 지정.

✔ 결과 확인

3.3.3. props 기본값 설정: defaultProps

✍ example

const MyComponent=props=>{
    return <div>안녕하세요 제 이름은 {props.name}입니다. </div>;
};
MyComponent.defaultProps={
    name: '기본 이름'
};
export default MyComponent;
  • props 값을 따로 지정하지 않았을 때 보여줄 기본 값 defaultProps로 설정.

3.3.4. 태그 사이의 내용을 보여주는 children

✍ example

//App.js
import MyComponent from './MyComponent';

const App=()=>{
  return <MyComponent>리액트 </MyComponent>;
};

export default App;



//MyComponent.js
const MyComponent=props=>{
    return(
         <div>
            안녕하세요 제 이름은 {props.name}입니다. <br/>
            children값은 {props.children}
         </div>
        );
};
MyComponent.defaultProps={
    name: '기본 이름'
};
export default MyComponent;
  • props.children을 이용하여 부모 컴포넌트에서 MyComponent 태그 내부에 작성한 문자열을 보여줄 수 있음.

3.3.5. 비구조화 할당 문법을 통해 props 내부 값 추출하기

비구조화 할당 : 구조 분해 문법
✍ example

const MyComponent=props=>{
    const{name, children}=props;
    return(
         <div>
            안녕하세요 제 이름은 {name}입니다. <br/>
            children값은 {children}
         </div>
        );
};
MyComponent.defaultProps={
    name: '기본 이름'
};
export default MyComponent;
  • props.를 붙이지 않고 name과 children 값을 더 짧은 코드로 사용 가능.

3.3.6. propTypes를 통한 props 검증

컴포넌트의 필수 props를 지정하거나 props 타입을 지정할 때 propsTypes를 사용한다.
✍ example

//MyComponene.js
import PropTypes from 'prop-types';
const MyComponent=props=>{
   const{name, children}=props;
   return(
        <div>
           안녕하세요 제 이름은 {name}입니다. <br/>
           children값은 {children}
        </div>
       );
};
MyComponent.defaultProps={
   name: '기본 이름'
};
MyComponent.propTypes={
   name: PropTypes.string
}
export default MyComponent;
  • propTypes를 사용하기 위해서는 import을 사용해서 불러와야함.
  • name: PropTypes.string 은 name 값은 무조건 문자열로 전달해야 됨을 의미

✔ 결과 확인

  • App컴포넌트에서 name 값을 숫자로 전달한 경우 console창에 에러문 발생.

3.3.6.1. isRequired를 이용하여 필수 propTypes설정

✍ example

import PropTypes from 'prop-types';
const MyComponent=props=>{
    const{name, children, favoritenumber}=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;
  • favoritenumber 를 필수 props로 지정
  • propTypes를 지정할 때 isRequired 를 붙여주면 됨.

✔ 결과 확인

  • propsTypes를 지정하지 않았을 때 경고 메세지를 띄워줌.

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

✍ example

import { Component } from 'react';
import PropTypes from 'prop-types';

class MyComponent extends Component{
    render(){
    const{name, children, favoritenumber}=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;
  • 클래스형 컴포넌트에서 props를 사용하기 위해서는 render 함수 필요.
  • render 함수에서 this.props를 조회하면 됨.

❓ defaultProps와 propTypes는 꼭 사용해야 하나?
두 설정은 필수 사항이 아니므로 반드시 사용할 필요는 없다. 그러나 협업을 한다면 어떤 props가 필요한지 알 수 있기 때문에 유용하다.


3.4 state

stateprops
- 컴포넌트 내부에서 바뀔 수 있는 값
- 클래스형 컴포넌트가 가지는 state과 함수 컴포넌트에서 use State를 함수를 통해 사용 가능.
- 부모 컴포넌트가 설정하여 컴포넌트 자신은 props를 읽기 전용으로만 사용 가능.
- 즉, props를 바꾸기 위해서는 부모 컴포넌트에서 바꾸어야함.

3.4.1. 클래스형 컴포넌트의 state

✍ example

constructor(props){
        super(props);
            this.state={
                number:0
            };
}
  • 컴포넌트에 state를 설정할 때에는 constructor()메서드 이용.
  • 클래스형 컴포넌트에서 constructor를 작성할 때에는 반드시 super(props) 를 호출해서 리액트의 Component 클래스가 지닌 생성자 함수를 호출.
  • this.state 값에 초깃값 설정. 컴포넌트의 state는 객체 형식.

✍ example

 render(){
        const {number}=this.state;
        return(
            <div>
                <h1>{number}</h1>
                <button onClick={()=>{
                this.setState({number:number+1});}}
                >
                 +1
                 </button>
            </div>
            );
    }
  • render 함수에서 현재 state을 조회할 때에는 this.state 를 조회.
  • button안에 onClick이라는 값을 props로 넣음-> 버튼이 클릭 될 때 호출할 함수 설정.
  • this.setState()함수를 통해 state값 변경 가능.

✍ example

//App.js
import Counter from './Counter';

const App=()=>{
  return  <Counter/>;
};

export default App;
  • Counter를 App에 불러와서 렌더링.

✔ 결과 확인

3.4.1.2. state를 constructor에서 꺼내기

✍ example

class Counter extends Component{
    state={
        number:0, 
        fixednumber:0
    };
  • constructor 메서드를 선언하지 않고도 state의 초깃값 설정 가능

3.4.1.3. this.setState에 객체 대신 함수 인자 전달하기

✍ example

 <button onClick={()=>{
                this.setState(prevState=>{ 
                    return {
                        number: prevState.number+1
                    };
                });
                this.setState(prevState=>({
                    number:prevState.number+1
                }));
            }}
                >
                 +1
</button>
  • this.setState을 사용할 때에는 state값을 비동기적으로 업데이트하므로 함수 내부에서 this.setState을 두 번 호출한다고 해도 버튼을 클릭할 때 값이 1씩 더해짐.
  • this.setState에 객체 대신 함수를 인자로 넣어주면 됨.
  • prevState은 기존 상태.
  • 위의 this.setState코드와 아래 this.setState 코드는 완전히 같은 기능을 하지만 아래 코드는 함수에서 바로 객체를 반환한다는 의미.

3.4.2. 함수 컴포넌트에서 useState 사용하기

Hooks를 사용해서 함수 컴포넌트에서도 state을 사용할 수 있다. 함수 컴포넌트에서 state을 사용할 때에는 useState라는 함수를 이용한다.

3.4.2.1. 배열 비구조화 할당

✍ example

const arrat=[1, 2];
const[one, two]=array;
  • 배열 비구조화 할당을 통해 배열 안에 있는 값을 쉽게 추출 가능.

3.4.2.2. useState 사용하기

✍ example

//Say.js
import { useState } from 'react';
const Say=()=>{
    const[text, setText]=useState('');
    const onClickEnter=()=>setText('안녕하세요!');
    const onClickLeave=()=>setText('안녕히가세요~');

    return(
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1>{text}</h1>
        </div>

    );
};

export default Say;
  • useState()를 호출하면 배열이 반환, 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꿔주는 함수(setter 함수).
  • useState()을 사용할 때에는 초깃값이 객체가 아니어도 됨. 값의 형태는 자유.
  • const[text, setText]=useState('');에서 text, setText의 이름은 자유롭게 변경 가능.

✔ 결과 확인

3.4.2.3. 한 컴포넌트 내에서 useState 여러 번 사용하기

✍ example

import { useState } from 'react';
const Say=()=>{
    const[text, setText]=useState('');
    const onClickEnter=()=>setText('안녕하세요!');
    const onClickLeave=()=>setText('안녕히가세요~');
    const[color, setColor]=useState('black');

    return(
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1 style={{color}}>{text}</h1>
            <button style={{color:'red'}} onClick={()=>setColor('red')}>빨간색</button>
            <button style={{color: 'green'}} onClick={()=> setColor('green')}>초록색</button>
            <button style={{color:'pink'}} onClick={()=> setColor('pink')}>pink</button>
        </div>

    );
};

export default Say;
  • useState는 한 컴포넌트에서 여러번 사용 가능.

✔ 결과 확인

✔ 마치며

다음 시간에는 이벤트 핸들링에 대하여 포스팅을 해보겠습니다. 😉

0개의 댓글