Notice
Recent Posts
Recent Comments
Link
Tags
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

JongDDA의 한걸음 한걸음씩

[리액트(React)] 리액트 훅(React Hook) 본문

개발/프론트엔드

[리액트(React)] 리액트 훅(React Hook)

종따 2021. 5. 15. 17:42
728x90

리액트 컴포넌트는 클래스형 컴포넌트(Class Component)함수형 컴포넌트(Functional Component)로 나뉜다.

기존의 개발방식은 일반적으로 함수형 컴포넌트를 주로 사용하되 state 나 Liffe Cycle method를 사용해야 할 때에만

클레스형 컴포넌트를 사용하는 방식 이었는데

(함수형 컴포넌트에선 state 관리(this 키워드를 통한 관리, setState를 통한 변경)가 불가하다 또한 생명주기 메소드 미제공)

이러한 이유에는 클래스형 컴포넌트가 가지는 아래의 단점 때문이다.

(로직의 재사용 불편, 코드를 작성하기가 함수에 비해 비교적 불편하고 어렵다)

 

그러나

2019년 훅(Hook)의 등장으로 함수형 컴포넌트에서도 이러한 클래스형 컴포넌트의 작업들을 할 수 있게 되었다.

(함수형 컴포넌트에서 state 관리, 생명주기 관리 등을 할 수 있도록 제공되는 함수)
(클레스 기반 컴포넌트를 완전히 대체할 수 있다)

-> 기존의 클래스형 컴포넌트가 가지고 있던 복잡성, 재사용성의 단점들까지 해결

 

그럼 동일한 기능을 클래스형 컴포넌트useState이라는 hook을 사용한 함수형 컴포넌트로 각각 구현해보고 비교해보면

 

 

1. 클래스형 컴포넌트

import React from "react";

class App extends React.Component {
  state = {
      number: 0
  };
  render() {
    return (
      <div>
       <h1>{this.state.number}</h1>
       <button onClick={this.handleClickDecrement}>-</button>
        <button onClick={this.handleClickIncrement}>+</button>
      </div>
    );
  }
  handleClickIncrement = () => {
    this.setState(state => ({
      number: state.number + 1
    }));
  };
  handleClickDecrement = () => {
    this.setState(state => ({
      number: state.number - 1
    }));
  };
}

export default App;

 

2. useState이라는 hook을 사용한 함수형 컴포넌트

import { useState } from 'react' // 리액트 훅도 리액트의 일부이므로 리액트 모듈에서 가져온다

const App = () => {
  // useState(초깃값) : [상태값과 상태변경함수]를 반환한다!
  // number : 0으로 초기화된 상태 변수
  // changeNumber : 인자로 변경값을 받는 상태 변경 함수
  const [number, changeNumber] = useState(0) 
  
  return <div>
    <h1>{number}</h1>
    <button onClick = {()=>{changeNumber(number-1)}}>-</button>
    <button onClick = {()=>{changeNumber(number+1)}}>+</button>
  </div>
}

export default App

 

-> 코드가 많이 줄어듦을 알 수 있다.

 

useState클래스형 컴포넌트의 state의 선언과 관리를 짧고 직관적인 코드로 가능하게 해주는 hook이다.

number라는 state과 changeNumber라는 state 변경함수를 useState을 통해 선언하였다.

 

 

다른 예제를 보자면

 

import {useState} from 'react'

const Number = () => {

    const [ number, setNumber ] = useState(0)

    return <div>
        <h1>{number}</h1>
        <button onClick={()=> setNumber(number == - 10 ? number:number -2)}>-</button>
        <button onClick={()=> setNumber(number == 10 ? number:number +2)}>+</button>
    </div>
}

export default Number

이번엔 아까 예제에 삼항연산자를 넣어 조건을 걸어준 코드이다.

 

 

그럼 2개 이상의 state를 관리하려면 어떻게 해야할까

state가 n개 라면, useState도 n번 호출하면 된다

 

import { useState } from 'react'
// 2개 이상의 상태를 관리하자
const TextInput = () =>{

// 상태가 n개라면, useState도 n번 호출한다!
const [myName, changeMyName ] = useState("")
const [nickName, changeNickName] = useState("")

    return <div>
        <h1>이름을 입력하세요</h1>
        <input onChange= {e=> changeMyName(e.target.value)} type="text" placeholder="이름" />
        <h1>별명을 입력하세요</h1>
        <input onChange= {e=> changeNickName(e.target.value)} type="text" placeholder="별명" />
        {myName == "" ? <p></p> : <p>너의 이름은 : {myName}</p>}
        {nickName == "" ? <p></p> : <p>너의 별명은 : {nickName}</p>}
    </div>
}

export default TextInput

함수 컴포넌트에서의 속성을 활용하여 다음과 같은 코드도 만들 수 있다.

import {useState} from 'react'

// 함수 컴포넌트에서는 속성을 읽을 때, 매개변수를 활용한다!
const ColorBox = (props)=>{
    
    const [color, changeColor] = useState("black")

// 스타일 객체를 지역변수로!
    const divStyle = {
        width: 200, height:200,
        backgroundColor: color,
        color: "white", display: "flex",
        justifyContent: 'center', alignItems: 'center'
    }
// 지역 변수로써의 화살표 함수
const handleChange = e=>changeColor(e.target.value)

    return <div>
        <input type="text" placeholder="색상" onChange = {handleChange}/>
        <div style={divStyle}>{props.content}</div>
    </div>
}

export default ColorBox

훅을 커스텀 함수에서 사용해보는 방법

import {useState} from 'react'
// 훅을 커스텀 함수에서 사용해보기 

// 컴포넌트가 아닌 기능으로써의 함수, useInput
// initialValue : 상태의 초기값
// customValidator : 값이 변경될 때 간단한 규틱을 적용하기 위한 데이터
const useInput = (initialValue, customValidator) =>{
    const [value, setValue] = useState(initialValue)   
    // 커스텀벨리데이터가 적용된 상태값 변경 함수 만들기
    const handleChange = (e) =>{
        const currentValue = e.target.value //현재 값 읽기
        if(typeof customValidator === 'function'){
           if (customValidator(currentValue) == true){ 
           setValue(currentValue)
            }
        }
    }
    // setValue 에 기능을 추가한 handleChange를 내보내겠다!
    return {value, handleChange}
}

// 컴포넌트 함수
const Text = ()=>{
    // customValidator 만들어서 인자로 전달하기!
    // 값의 길이가 10보다 작아야 true 를 반환하는 함수!
    const customValidator = (value) => value.length < 10
    const {value, handleChange} = useInput("초기값", customValidator)

    return <div>
        <h1>커스텀 훅을 통해서 상태관리 하는중</h1>
        <input type="text" value={value} onChange={e => handleChange(e)}/>
        <p>{value}</p>
    </div>
}

export default Text

728x90
반응형
Comments