๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ

 


1. React hook ์ด๋ž€?

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ state๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๊ณ , ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ์„ฑ, ๋ณ€๊ฒฝ, ์†Œ๋ฉธ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ์ธ ๋ผ์ดํ”„์‚ฌ์ดํด API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. ๊ทธ์ € ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹œํ‚ค๋Š” ์ผ๋งŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๋‹จ์ˆœํ•œ ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์‚ฌ์šฉ๋๋‹ค. ํ•˜์ง€๋งŒ 16.8 ๋ฒ„์ „๋ถ€ํ„ฐ ํ›…(hook)์ด๋ผ๋Š” ๊ฐœ๋…์ด ๋„์ž…๋˜๋ฉฐ, ์ด ๋‘˜์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค. ๋‘ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์— "hook into”, ๋Œ์–ด์™€ ์—ฐ๊ฒฐ ํ•œ๋‹ค๊ณ  ํ•ด์„œ "hook"์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ๋˜ํ•œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ท€์ฐฎ๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” didMount, render, this ๋“ฑ ๋Œ€์‹ , ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ๋กœ ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค.

 

Class Component

import { Component } from 'react';

class Example extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

 

Functional Component using hooks

import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

- ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ , ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.

- ํ•˜์ง€๋งŒ Facebook์ด Class Component๋ฅผ ๊พธ์ค€ํžˆ ์ง€์›ํ•œ๋‹ค๊ณ  ์•ฝ์†ํ–ˆ์œผ๋‹ˆ, ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์•Œ์•„๋‘์ž

 

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” props๊ฐ’์„ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

function FuncComp(props){
  return(<h1>{props.count}</h1>)
}

function FuncComp({count}){
  return(<h1>{count}</h1>)
}

2. useState

- default ๊ฐ’ ์—†์ด useState()๋ฅผ ์ž‘์„ฑํ•˜๋ฉด,  state๊ฐ’์€ undefined๊ฐ€ ๋œ๋‹ค.

import {useState} from 'react'

function FuncComp(props){
  
  var countState = useState(props.count) 
  // useState์˜ ๋ฐ˜ํ™˜๊ฐ’: ๋ฐฐ์—ด
  // useState(initValue)
  
  var count = countState[0]              // ์ฒซ ๋ฒˆ์งธ ๊ฐ’: state ๊ฐ’
  var setCount = countState[1]           // ๋‘ ๋ฒˆ์งธ ๊ฐ’: state๋ฅผ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜
  
  return(
    <h1>{count}</h1>
    <button onClick={()=>setCount(count+1)}>
  )
}

 

์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ๋งŒ ํ›…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

-hook ์€ for๋ฌธ, if๋ฌธ, ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ˜ธ์ถœ ๋  ์ˆ˜ ์—†๋‹ค.

import {useState} from 'react'

function Component(props){
	var [count, setCount] = useState(props.count)  โœ…
    
  function inner() {
  	var [count, setCount] = useState(props.count)  โŒ
  }
  
  if(count){
  	var [count, setCount] = useState(props.count)  โŒ
  }
  
  return(
  	var [count, setCount] = useState(props.count) โŒ
    <button onClick={()=>setCount(count+1)}></button>
  )
}

 

3. useInput

import {useState} from "react"

const useInput = (initialValue, validator) => {
  const [value, setValue] = useState(initialValue);
  const onChange = (event) => {
    const {
      target: { value }
    } = event;
    let willUpdate = true;
    if (typeof validator === "function") {
      willUpdate = validator(value);
    }
    if (willUpdate) {
      setValue(value);
    }
  };
  return { value, onChange };
};
const App = () => {
  const maxLen = (value) => value.length < 10;
  const name = useInput("Mr.", maxLen);
  return (
    <>
      <div className="APP">
        <h1>Hello</h1>
        <input placeholder="Name" {...name} />
      </div>
    </>
  );
};

 

  1. {value"e", onChangeƒ onChange()}
  2. {value"e2", onChangeƒ onChange()}
  3. {value"e22", onChangeƒ onChange()}

1. onChange: ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ ๋งˆ๋‹ค onChangeํ•จ์ˆ˜๊ฐ€ ๊ณ„์† ์ž‘๋™ํ•˜๋ฉฐ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ๋ฅผ ๊ฑฐ์ณ DOM์„ refreshํ•œ๋‹ค.

 

2. onChangeํ•จ์ˆ˜๋Š” event๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ๋‹ค๋ฅธ function์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ˜๋ช…์ ์ธ ์ผ์ด๋‹ค. ์ด๋ฒคํŠธ๋ฅผ ๋ถ„๋ฆฌ๋œ ํŒŒ์ผ, ๋‹ค๋ฅธ entity์— ์—ฐ๊ฒฐํ•ด์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4. useTabs

import React, { useState } from "react";

const content = [
  {
    tab: "Section1",
    content: "I am content1"
  },
  {
    tab: "Section2",
    content: "I am content2"
  }
];

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  if (!allTabs || !Array.isArray(allTabs)) {
    return;
  }
  return {
    currentItem: allTabs[currentIndex],
    changeItem: setCurrentIndex
  };
};
const App = () => {
  const { currentItem, changeItem } = useTabs(0, content);
  return (
    <div className="App">
      {content.map((section, index) => (
        <button onClick={() => changeItem(index)}>{section.tab}</button>
      ))}
      <div>{currentItem.content}</div>
    </div>
  );
};

export default App;
๋ฐ˜์‘ํ˜•