분류 Reactjs

React Hooks 시작하기

컨텐츠 정보

  • 조회 345 (작성일 )

본문

후크는 React v16.8을 통해 프로덕션에 출시되었으며 React를 생각하고 사용하는 방식을 완전히 바꿔 놓았습니다. 

React Hooks를 사용하면 객체 지향 (클래스) 방식 대신 함수적 방식을 사용하여 컴포넌트를 작성할 수 있습니다.


여기서 큰 문제는 – React Hooks 란 무엇이며 왜 모두가 그들에 대해 흥분 하는지 입니다. 그러나 React Hooks가 실제로 무엇인지 논의하기 전에 현재 React가 직면하고 있는 과제와 Hooks가 이러한 과제를 해결하는 데 어떻게 도움이 되는지 이해하는 것이 매우 중요합니다.


더 깊이 이해하려면 React Hooks에 대한 공식 문서를 확인하십시오.


React의 과제 


과제 1 – 다른 구성 요소간에 상태 저장 논리를 재사용 하기 어려움 


React에서는 다른 구성 요소 간에 상태 저장 논리를 재사용 하기가 매우 어렵습니다. React는 컴포넌트에 재사용 가능한 동작을 첨부하는 방법을 제공하지 않습니다.


따라서 React와 함께 작업했다면 이 문제를 해결하는 데 도움이 되는 상위 컴포넌트나 렌더링 props과 같은 것을 이해합니다.


그러나 이러한 패턴을 사용하더라도 까다롭고 따라하기 어려운 구성 요소를 리팩터링 해야 합니다. 따라서 모든 React 요구 사항은 상태 저장 논리를 공유하는 더 좋은 방법입니다. 여기에 React Hooks가 설치됩니다.


과제 2 – 복잡한 구성 요소를 이해하기 어렵다 


우리가 React에서 보았던 또 다른 과제는 복잡한 구성 요소를 이해하기 어렵다는 것입니다. 각 수명주기 방법에는 종종 관련 없는 논리가 혼합되어 있습니다.


따라서 상호 관련이 있는 코드는 이러한 수명주기 방법으로 분리되고 완전히 관련되지 않은 코드는 단일 방법으로 결합되어 버그와 불일치를 쉽게 도입 할 수 있습니다.


대부분의 경우 상태 저장 논리가 모든 위치에 있어 테스트하기가 어렵기 때문에 이러한 구성 요소를 더 작은 구성 요소로 나눌 수 없습니다.


Hook가 React의 도전을 어떻게 극복합니까? 


후크를 사용하면 구성 요소에서 상태 저장 논리를 추출하여 독립적으로 테스트하고 재사용 할 수 있습니다. 후크를 사용하면 구성 요소 계층 구조를 변경할 필요 없이 해당 상태 저장 논리를 재사용 할 수 있으므로 여러 구성 요소 간에 후크를 쉽게 공유 할 수 있습니다.


후크를 사용하면 수명주기 방식을 강요하지 않고 관련 부분을 기준으로 구성 요소를 더 작은 기능으로 분할 할 수 있습니다.


따라서 논리와 해당 수명 주기 방법에 따라 앱 관련 문제를 분리 할 수 ​​있습니다.


간단한 온도 앱을 만들어서 React Class와 React Hooks의 기본적인 구문 차이를 이해합니다.


그림을 보자 –


React 클래스를 사용한 간단한 온도 앱 


import React, { Component } from 'react';
/**
* @desc TemperatureInput component to render input box and
* update the props when change temperature value
* @param {func} onChange
* @param {string} value
* @param {string} scale
*/
class TemperatureInput extends Component {
/**
* @desc Call when we change the temperature value and
* call the parent onChange method to update the props
* @param {object} event
*/
handleChange = (event) => {
this.props.onChange(event.target.value);
}
render() {
const { value, scale } = this.props;
return (
<div className="container">
<form>
<div className= "form-group">
<h3>Enter Temperature in {scale}: </h3>
<input className="form-control container text-center" id="focusedInputed" type="text" value={value}
onChange={this.handleChange} />
</div>
</form>
</div>
);
}
}
/**
* @desc Calculator component that will handle the calculations
*/
export default class Calculator extends React.Component {
constructor(props) {
super(props);
this.state = {
scale: 'Celsius',
value: ''
};
}
/** @desc When component will setup get the current temperature */
componentDidMount = () => {
fetch("http://api.apixu.com/v1/current.json?key=478f53ca816141a79a8102217191906&q=Mohali")
.then(res => res.json())
.then(
(result) => {
this.setState({value: result.current.temp_c})
},
(error) => {
console.log('error=======', error)
}
)
}
/** @desc Whenever component will update console the values */
componentDidUpdate = () => {
const { scale, value } = this.state
setTimeout(() => {
console.log(`Changed ${scale} value to ${value} `);
}, 100);
}
/** @desc When component will unmount empty state value */
componentWillUnmount = () => {
this.setState({value: ''})
}
/**
* @desc Call when we change the Celsius value
* @param {string} value
*/
handleCelsiusChange = (value) => {
this.setState({scale: 'Celsius', value});
}
/**
* @desc Call when we change the Fahrenheit value
* @param {string} value
*/
handleFahrenheitChange = (value) => {
this.setState({scale: 'Fahrenheit', value});
}
/**
* @desc To covert the celsius, fahrenheit values
* @param {string} value
* @param {func} convert
*/
tryConvert = (value, convert) => {
const input = parseFloat(value);
if (Number.isNaN(input)) {
return '';
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();
}
/** @desc To convert value in celsius */
toCelsius = (fahrenheit) => {
return (fahrenheit - 32) * 5 / 9;
}
/** @desc To convert value in fahrenheit */
toFahrenheit = (celsius) => {
return (celsius * 9 / 5) + 32;
}
render() {
const { scale, value } = this.state;
const celsius = scale === 'Fahrenheit' ? this.tryConvert(value, this.toCelsius) : value;
const fahrenheit = scale === 'Celsius' ? this.tryConvert(value, this.toFahrenheit) : value;
return (
<div className="text-center container-fluid">
<TemperatureInput
scale="Celsius"
value={celsius}
onChange={this.handleCelsiusChange} />
<TemperatureInput
scale="Fahrenheit"
value={fahrenheit}
onChange={this.handleFahrenheitChange} />
</div>
);
}
}

여기에서 React 클래스 컴포넌트를 사용하여 간단한 온도 앱을 만들었습니다.


  • 생성자에서 초기 상태 값으로 계산기 클래스 구성 요소를 만듭니다.
  • 우리는 다른 수명주기 방법을 사용합니다 –
    ‘componentDidMount’– 구성 요소가 마운트되면 메소드가 호출됩니다.
    ‘componentDidUpdate’– 구성 요소 소품 업데이트시 메소드가 호출됩니다.
    ‘componentWillUnmount’– 구성 요소를 마운트 해제하고 파기하기 전에 메소드가 호출됩니다.
  • 우리는 다양한 계산기 작업에 다른 계산기 방법을 사용합니다.
  • 입력 상자와 온도 값을 렌더링하는 TemperatureInput 구성 요소를 사용합니다.

React Hooks를 사용한 간단한 온도 앱 


이것은 React 클래스와 같은 것을 렌더링 합니다. Hooks에는 관련 사항과 이들이 속한 수명주기 방법을 기반으로 하는 코드가 있습니다.


import React, {useState, useEffect} from 'react';
/**
* @desc TemperatureInput functional component to render input box and
* update the props when change temperature value
* @param {func} onChange
* @param {string} value
* @param {string} scale
*/
const TemperatureInput = (props) => {
const {scale, value} = props
/**
* @desc Call when we change the temperature value and
* call the parent onChange method to update the props
* @param {object} event
*/
const handleChange = (e) => {
props.onChange(e.target.value);
}
return (
<div className="container">
<form>
<div className= "form-group">
<h3>Enter Temperature in {scale}: </h3>
<input className="form-control container text-center" id="focusedInputed" type="text" value={value}
onChange={handleChange} />
</div>
</form>
</div>
);
}
/**
* @desc Calculator functional component that will handle the calculations
*/
const Calculator = () => {
const [ scale, setScale ] = useState('Celsius')
const [ value, setValue] = useState('')
/**
* @desc useEffect hook to get the temperature value
* @return {func} that will call when component unmount
*/
useEffect( () => {
fetch("http://api.apixu.com/v1/current.json?key=478f53ca816141a79a8102217191906&q=Mohali")
.then(res => res.json())
.then(
(result) => {
setValue(result.current.temp_c)
},
(error) => {
console.log('error=======', error)
}
)
return () => { setScale("") }
},[])
/**
* @desc useEffect hook that will console the values when props update
*/
useEffect( () => {
setTimeout(() => {
console.log(`Changed ${scale} value to ${value}`);
}, 100);
})
/**
* @desc Call when we change the Celsius value
* @param {string} value
*/
const handleCelsiusChange = (value) => {
setValue(value)
}
/**
* @desc Call when we change the Fahrenheit value
* @param {string} value
*/
const handleFahrenheitChange = (value) => {
setScale('Fahrenheit')
setValue(value)
}
/**
* @desc To covert the celsius, fahrenheit values
* @param {string} value
* @param {func} convert
*/
const tryConvert = (value, convert) => {
const input = parseFloat(value);
if (Number.isNaN(input)) {
return '';
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();
}
/** @desc To convert value in celsius */
const toCelsius = (fahrenheit) => {
return (fahrenheit - 32) * 5 / 9;
}
/** @desc To convert value in fahrenheit */
const toFahrenheit = (celsius) => {
return (celsius * 9 / 5) + 32;
}
const celsius = scale === 'Fahrenheit' ? tryConvert(value, toCelsius) : value;
const fahrenheit = scale === 'Celsius' ? tryConvert(value, toFahrenheit) : value;
return (
<div className="text-center container-fluid">
<TemperatureInput
scale="Celsius"
value={celsius}
onChange={handleCelsiusChange} />
<TemperatureInput
scale="Fahrenheit"
value={fahrenheit}
onChange={handleFahrenheitChange} />
</div>
);
}
export default Calculator

여기에서 Hooks를 사용하여 동일한 온도 앱을 만들었습니다.

  • setState Hook를 사용하여 초기 상태 값으로 계산기 기능 구성 요소를 작성합니다.
  • 우리는 useEffect Hook를 사용합니다. 날씨 API에서 결과를 가져옵니다. 처음에 구성 요소는 setState Hook를 사용하여 값을 렌더링하고 설정합니다. 각 업데이트에서 실행 효과를 방지하려면 두 번째 인수에서 비워 두어야 합니다. 이것은 componentDidMount와 유사합니다. 그런 다음 componentWillUnmount와 유사하게 작동하는 함수를 반환합니다. componentDidUpdate와 유사한 모든 업데이트에서 실행될 다른 useEffect Hook를 만듭니다.
  • 우리는 다양한 계산기 작업에 다른 계산기 방법을 사용합니다.
  • 입력 상자와 온도 값을 렌더링 하는 TemperatureInput 기능 구성 요소를 사용합니다.

Simple temperature app using React Class and React Hooks 


React Hooks란 무엇입니까? 


후크는 클래스 없이 상태 및 수명주기 메소드와 같은 React 기능을 제공하는 함수입니다. 후크를 사용하면 React 기능에 연결할 수 있습니다.


일반적으로 사용되는 React Hooks 


상태 훅 (State Hook) 


함수 구성 요소 내에서 호출하여 로컬 상태를 추가합니다.

가져 오기 {useState } from ‘react’;

그러면 React는 다시 렌더링간에 이 상태를 유지합니다. 따라서 기능 컴포넌트를 사용하고 이 상태 후크를 추가 할 수 있습니다.


컨텍스트 훅 


컨텍스트 오브젝트를 승인하고 해당 컨텍스트의 현재 컨텍스트 값을 리턴합니다.

import React, { useContext } from ‘react’;


컨텍스트에 액세스하여 구독 할 수 있습니다.


Effect Hook 


함수 구성 요소에서 부작용을 수행하는 기능을 추가합니다.


import React, { useEffect } from ‘react’;


Custom Hooks 


사용자 정의 후크를 사용하면 자신 만의 후크를 만들 수 있습니다. 사용자 정의 후크는 이름이 "use"로 시작하고 그 안에 다른 후크를 호출 할 수 있는 JavaScript 함수입니다.

두 개의 자바 스크립트 함수 간에 논리를 공유하려면 세 번째 함수로 추출합니다. 후크와 기능 구성 요소는 모두 함수이므로 작동합니다.


간단한 드래그 앤 드롭 앱 구축 


구성 요소간에 재사용 가능한 논리를 만드는 방법과 차이점을 구별하는 방법을 보여주는 매우 기본적인 끌어서 놓기 앱을 작성해 보겠습니다.

  • React Class Components
  • Higher-Order Component
  • React Hooks


React Class를 사용한 간단한 드래그 앤 드롭 앱 


먼저, 사람과 선호하는 컴포넌트를 만들고 index.js로 두 파일을 모두 호출합니다.


React 클래스 컴포넌트를 사용하는 person.js –


import React, { Component } from 'react';
import Draggable from 'react-draggable'
import { PersonIcon } from '../icons'
/**
* @desc person class component that that render the person drag icon
* and handle the drag drop operations
*/
class Person extends Component {
constructor() {
super();
this.state = {
activeDrag: 0,
deltaPosition: {
x: 0, y: 0
}
};
}
/** @desc When component will setup */
componentDidMount = () => {
this.setState({deltaPosition: { x: 10, y: 10}})
}
/** @desc When component will unmount set default values */
componentWillUnmount = () => {
this.setState({deltaPosition: { x: 0, y: 0}})
}
/** @desc when we start to drag set activeDrag to true*/
handleStart = () => {
let { activeDrag } = this.state
this.setState({activeDrag: ++ activeDrag});
}
/**
* @desc change the positions when we drag drop component
*/
handleDrag = (e, ui) => {
const {x, y} = this.state.deltaPosition;
this.setState({
deltaPosition: {
x: x + ui.deltaX,
y: y + ui.deltaY,
}
});
}
/** @desc when we stop drag set activeDrag to false*/
handleStop = () => {
let { activeDrag } = this.state
this.setState({activeDrag: -- activeDrag});
}
render() {
let { deltaPosition, activeDrag } = this.state
return(
<>
<div> Person Active Drag: {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<div className="handle"><PersonIcon /> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
<br/>
<br/>
</>
)
}
}
export default Person

React 클래스 컴포넌트를 사용하는 favorite.js –


import React, { Component } from 'react';
import Draggable from 'react-draggable'
import { FavoriteIcon } from '../icons'
/**
* @desc Favorite class component that that render the favorite drag icon
* and handle the drag drop operations
*/
class Favorite extends Component {
constructor() {
super();
this.state = {
activeDrag: 0,
deltaPosition: {
x: 0, y: 0
}
};
}
/** @desc When component will setup */
componentDidMount = () => {
this.setState({deltaPosition: { x: 10, y: 10}})
}
/** @desc When component will unmount set default values */
componentDidUpdate = () => {
console.log('value updated in Favorite component')
}
/** @desc when we start to drag set activeDrag to true*/
handleStart = () => {
let { activeDrag } = this.state
this.setState({activeDrag: ++ activeDrag});
}
/**
* @desc change the positions when we drag drop component
*/
handleDrag = (e, ui) => {
const {x, y} = this.state.deltaPosition;
this.setState({
deltaPosition: {
x: x + ui.deltaX,
y: y + ui.deltaY,
}
});
}
/** @desc when we stop drag set activeDrag to false*/
handleStop = () => {
let { activeDrag, } = this.state
this.setState({activeDrag: -- activeDrag});
}
render() {
let { deltaPosition, activeDrag } = this.state
return(
<>
<div >Favorite Active Drag : {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<div className="handle"><FavoriteIcon/> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
</>
)
}
}
export default Favorite

고차 컴포넌트를 사용하는 간단한 드래그 앤 드롭 앱 


논리를 하나의 파일로 구현하고 두 구성 요소 내에서 사용합니다.


person.js


import React, { Component } from 'react';
import Draggable from 'react-draggable'
import withContent from "./withContent";
import { PersonIcon } from '../icons'
/**
* @desc Person class component that that render the person drag icon
* and handle the drag drop operations in withContent HOC
* @param {object} dragDetails
* @param {func} handleStart
* @param {func} handleDrag
* @param {func} handleStop
* @param {object} deltaPosition
* @param {bool} activeDrag
*/
class Person extends Component {
render() {
const { dragDetails, handleStart, handleDrag, handleStop } = this.props
const { deltaPosition, activeDrag } = dragDetails
return(
<>
<div>Person Active Drag: {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={handleStart}
onDrag={handleDrag}
onStop={handleStop}>
<div className="handle"><PersonIcon /> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
<br/>
<br/>
</>
)
}
}
export default withContent(Person)

favorite.js


import React, { Component } from 'react';
import Draggable from 'react-draggable'
import withContent from "./withContent";
import { FavoriteIcon } from '../icons'
/**
* @desc Favorite class component that that render the favorite drag icon
* and handle the drag drop operations in withContent HOC
* @param {object} dragDetails
* @param {func} handleStart
* @param {func} handleDrag
* @param {func} handleStop
* @param {object} deltaPosition
* @param {bool} activeDrag
*/
class Favorite extends Component {
render() {
const { dragDetails, handleStart, handleDrag, handleStop } = this.props
const { deltaPosition, activeDrag } = dragDetails
return(
<>
<div>Favorite Active Drag: {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={handleStart}
onDrag={handleDrag}
onStop={handleStop}>
<div className="handle"><FavoriteIcon /> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
<br/>
<br/>
</>
)
}
}
export default withContent(Favorite)

그리고 이것은 컴포넌트들 사이에서 유사한 기능을 수행하는 상위 컴포넌트 파일입니다. 두 구성 요소 모두에 대해 유사한 논리가 작동합니다.


withContent.js


import React from "react";
/**
*
* @desc WrappedComponent HOC to handle drag drop operations of both
* person and favorite component
*/
const withContent = WrappedComponent =>
class extends React.Component {
constructor() {
super();
this.state = {
activeDrag: 0,
deltaPosition: {
x: 0, y: 0
}
};
}
/** @desc When component will setup */
componentDidMount = () => {
this.setState({deltaPosition: { x: 10, y: 10}})
}
/** @desc When component will update console the values */
componentDidUpdate = () => {
const {deltaPosition} = this.state
console.log('x=== ', deltaPosition.x)
console.log('y=== ', deltaPosition.y)
}
/** @desc When component will unmount set default values */
componentWillUnmount = () => {
this.setState({deltaPosition: { x: 0, y: 0}})
}
/** @desc when we start to drag set activeDrag to true*/
handleStart = () => {
let { activeDrag } = this.state
this.setState({activeDrag: ++ activeDrag});
}
/**
* @desc change the positions when we drag drop component
*/
handleDrag = (e, ui) => {
const {x, y} = this.state.deltaPosition;
this.setState({
deltaPosition: {
x: x + ui.deltaX,
y: y + ui.deltaY,
}
});
}
/** @desc when we stop drag set activeDrag to false*/
handleStop = () => {
let { activeDrag, } = this.state
this.setState({activeDrag: -- activeDrag});
}
render() {
return <WrappedComponent dragDetails={this.state} handleStart = {this.handleStart}
handleDrag = {this.handleDrag} handleStop = {this.handleStop} />;
}
};
export default withContent;

React Hooks를 사용한 간단한 드래그 앤 드롭 앱 


person.js


import React from 'react';
import Draggable from 'react-draggable'
import { useContent } from './useContent'
import { PersonIcon } from '../icons'
/**
* @desc Person functional component that that render the person drag icon
* and handle the drag drop operations in useContent Hook.
* @param {object} dragDetails
* @param {func} handleStart
* @param {func} handleDrag
* @param {func} handleStop
* @param {object} deltaPosition
* @param {bool} activeDrag
*/
const Person = () => {
let { activeDrag, deltaPosition, useHandleStart, useHandleStop, useHandleDrag } = useContent()
return(
<>
<div>Person Active Drag : {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={useHandleStart}
onDrag={useHandleDrag}
onStop={useHandleStop}>
<div className="handle"> <PersonIcon/> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
<br/>
<br/>
</>
)
}
export default Person

favorite.js


import React from 'react';
import Draggable from 'react-draggable'
import { useContent } from './useContent'
import { FavoriteIcon } from '../icons'
/**
* @desc Favorite functional component that that render the favorite drag icon
* and handle the drag drop operations in useContent Hook.
* @param {object} dragDetails
* @param {func} handleStart
* @param {func} handleDrag
* @param {func} handleStop
* @param {object} deltaPosition
* @param {bool} activeDrag
*/
const Favorite = () => {
let { activeDrag, deltaPosition, useHandleStart, useHandleStop, useHandleDrag } = useContent()
return(
<>
<div>Person Active Drag : {activeDrag}</div>
<Draggable
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
// grid={[25, 25]}
bounds={{top: 0, left: 0, right: 150, bottom: 150}}
scale={1}
onStart={useHandleStart}
onDrag={useHandleDrag}
onStop={useHandleStop}>
<div className="handle"><FavoriteIcon/> <br/>(x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)})</div>
</Draggable>
</>
)
}
export default Favorite

그리고 이것은 컴포넌트의 유사한 기능을 수행 할 사용자 정의 후크 파일입니다.


useContent.js


import { useState, useEffect } from "react";
/**
*
* @desc useContent Hook to handle drag drop operations of both
* person and favorite component
*/
export const useContent = () => {
let [activeDrag, setActiveDrags] = useState(0);
let [deltaPosition, setDeltaPosition] = useState({x: 0, y: 0});
/** @desc useEffect hook that will set the initial values */
useEffect(() => {
setDeltaPosition({x: 10, y:10})
},[])
/** @desc useEffect hook that will console the values every time props update */
useEffect(() => {
console.log('x=== ', deltaPosition.x)
console.log('y=== ', deltaPosition.y)
})
/** @desc when we start to drag set activeDrag to true*/
const useHandleStart = () => {
setActiveDrags(++activeDrag);
}
/** @desc when we stop drag set activeDrag to false*/
const useHandleStop = () => {
setActiveDrags(--activeDrag);
}
/**
* @desc change the positions when we drag drop component
*/
const useHandleDrag = (e, ui) => {
setDeltaPosition({x: deltaPosition.x + ui.deltaX, y: deltaPosition.y + ui.deltaY})
}
return {activeDrag, deltaPosition, useHandleStart, useHandleStop, useHandleDrag}
}

Simple Drag-drop app using React Class 

React Hooks 사용의 장점 


  • 후크는 작성하는 코드가 적기 때문에 많은 시간을 절약합니다. 번들 크기에서 바이트를 줄이므로 중간 크기 앱에서 작업 할 때 더 유용합니다.
  • Hooks로 작성된 코드는 깨끗하고 깔끔하며 이해하기 매우 쉽습니다.
  • Hooks로 작성된 코드는 더 나은 성능을 제공합니다.
  • 후크는 상태 생성을위한 논리와 상태 업데이트 방법을 분리하여 이제 논리를 공유 할 수 있습니다.


최종 테이크 아웃 

  • 최상위 레벨에서만 후크를 호출하십시오. 구성 요소가 렌더링 될 때마다 후크가 항상 동일한 순서로 호출되도록 합니다. React가 여러 상태 후크 호출 사이의 후크 상태를 올바르게 보존 할 수 있습니다.
  • React 기능 및 사용자 정의 후크의 후크 만 호출하십시오. 루프, 조건 또는 중첩 함수 내에서 호출하지 마십시오.
  • ‘사용; 사용자 정의 후크 앞에. 이 규칙은 매우 중요하며 규칙이 없으면 함수 내부에 후크 호출이 있는지 여부를 알 수 없으므로 규칙 위반을 자동으로 확인할 수 없습니다.
  • 구버전과 호환되는. 클래스는 후크와 함께 작동 할 수 있으므로 동일한 프로젝트에서 클래스와 후크를 사용할 수 있습니다.