React

Hooks

글로리. 2021. 7. 20. 17:25

Hooks

React v16.8에 도입된 기능으로 함수형 컴포넌트에서도 useState, useEffect 등의 기능을 제공하여 다양한 작업을 지원.

useState

가장 기본적인 hook으로 함수형 컴포넌트에서도 가변적인 상태를 지닐 수 있게 해준다.

useEffect

컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정. componentDidMount + componentDidUpdate 라고 보면 된다.

useReducer

useState보다 더 다양한 컴포넌트 상황에 따라 다양한 상태를 다른 값으로 업데이트 해주고 싶을 때 사용

import React, { useEffect, useState, useReducer } from 'react';

function reducer (state, action) {
    return {
        ...state,
        [action.name]: action.value
    };
}

const HooksSample = () => {
    // const [name, setName] = useState('');
    // const [nickname, setNickname] = useState(''); 
    const [state, dispatch] = useReducer(reducer, {
        name: '',
        nickname: ''
    });

    const {name, nickname} = state;
    const onChange = e => {
        dispatch(e.target);
    }

    // 사용법 1
    // useEffect(()=> {
    //     console.log('렌더링 완료')
    //     console.log('name ====' + name);
    //     console.log('nickname ====' + nickname);
    // })

    // 사용법 2
    // useEffect(() => {
    //     console.log('마운트 마운트');
    // },[])

    // 사용법 3
    // useEffect(() => {
    //     console.log('name ==== ' + name);
    //     console.log('nickname ==== ' + nickname);
    // },[name,nickname]);

    // 사용법 4
    useEffect(() => {
        console.log('effect');
        console.log(name);
        return () => {
            console.log('cleanUp');
            console.log(name);
        };
    },[name])

    // 사용법 5
    // useEffect(() => {
    //     console.log('effect');
    //     return () => {
    //         console.log('unmount');
    //     };
    // },[])

    // const onChangeName = e => {
    //     setName(e.target.value);
    // }

    // const onChangeNickname = e => {
    //     setNickname(e.target.value);
    // }

    return (
        <div style={{ margin: '10px 0 0 50px' }}>
            <h2>useState 여러번 사용하기</h2>
            <div>
                <input name='name' value={name} onChange={onChange} />
                <input name='nickname' value={nickname} onChange={onChange} />
            </div>
            <br />
            <div>
                <div>
                    <b>이름: </b> {name}
                </div>
                <br />
                <div>
                    <b>닉네임: </b> {nickname}
                </div>
            </div>
        </div>
    );
};

export default HooksSample;

useMemo

함수형 컴포넌트 내부에서 발생하는 연산을 최적화 할 수 있다.

useRef

함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해준다.

import React, { useState, useMemo, useCallback, useRef } from 'react';

const getAverage = numbers => {
    console.log('평균 계산중~~');
    if (numbers.length === 0) return 0;
    const sum = numbers.reduce((a, b) => a + b);
    return sum / numbers.length;
};


const Average = () => {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');
    const inputEl = useRef(null);

    const onChange = useCallback(e => {
        setNumber(e.target.value);
    },[]); // 컴포넌트가 처음 렌더링 될 때만 함수 생성

    const onInsert = useCallback(() => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
        inputEl.current.focus();
    },[number, list]); // number 혹은 list가 바뀌었을때만 함수 생성.

    const avg = useMemo(() => getAverage(list), [list]);

    return (
        <div style={{ margin: '10px 0 0 50px' }}>
            <h2>useMemo 사용하기</h2>
            <input value={number} onChange={onChange} ref={inputEl} />
            <button onClick={onInsert}>등록</button>
            <ul>
                {list.map((value, index) => (
                    <li key={index}>{value}</li>
                ))}
            </ul>
            <div>
                <b>평균값 : </b> {avg}
            </div>
        </div>
    );
};

export default Average;