본문 바로가기

React

React - Hooks _ useState / useEffect /useRef

 Hooks

: 함수형 컴포넌트에서 클래스형 컴포넌트에서 제공하는 기능(state,ref, life cycle function 등)을 지원하기 위해서 도입된 함수

 

1) useState

: 함수형 컴포넌트에서 상태(state)를 관리하기 위해서 사용

[상태변수 초기값, 상태변수를 변경하는 함수 ] 배열을 반환하는 함수

 

const [name,setName] = useState('');

 

App.js

import Info from './Info';

function App() {
  return (
    <>
      <Info />
    </>  
  );
}
export default App;

Info.js => 사용자이름과 별명을 관리하는 컴포넌트를 구현

import { useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

2) useEffect

클래스형 컴포넌트의 componentDidMount, componentDidUpdate, componentWillUnmount를 합친 사용법

useEffect(이펙트 함수, 의존성배열);

 

** 의존성 배열 : 이펙트가 의존하고 있는 배열 안에 있는 변수 중 하나라도 값이 변경되었을 때 이펙트 함수가 실행

 

Info.js => useEffect 추가 => 렌더링 될 때마다 이펙트 함수 실행

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    // 의존 배열을 생략 	⇒ 마운트, 업데이트 시 마다 이팩트 함수를 실행
    //                  	⇒ 렌더링 완료 시 마다 이팩트 함수를 실행
    useEffect(() => {
        console.log('렌더링이 완료되었습니다.');
        console.log({ name, nickname });
    });
    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

Info.js => 마운트 될때만 이펙트 함수가 실행되도록 수정

 

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    // 의존 배열로 빈 배열([])을 설정
    // ==> 마운트될 때만 이팩트 함수를 실행
    useEffect(() => {
        console.log('렌더링이 완료되었습니다.');
        console.log({ name, nickname });
    }, []);
    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

Info.js => 특정 값이 업데이트 될 때만 이펙트 함수가 실행되도록 수정 = 의존 배열에 검사할 상태 변수이름을 값으로 설정

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    // 마운트될 때와 name 상태변수가 변경될 때만 이팩트 함수가 실행
    useEffect(() => {
        console.log('렌더링이 완료되었습니다.');
        console.log({ name, nickname });
    }, [name]);
    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

Info.js => 후처리(cleanup) 함수를 추가

: component가 언마운트 또는 리렌더링되기 전에 어떤 작업을 수행하고 싶을때 cleanup 함수를 반환

 useEffect의 첫번째 파라미터로 전달되는 콜백 함수(이펙트 함수)가 반환하는 함수

 

Info.js  Info 컴포넌트를 보이고 / 숨기기

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    useEffect(() => {
        console.log('렌더링이 완료되었습니다.');
        console.log({ name, nickname });
        return () => console.log('cleanup', name);	⇐ componentWillUnmount() 함수와 동일한 역할
    }, [name]);					   의존 배열에 name 상태 변수가 설정되어 있기 때문에,
    return (						   name 상태 변수가 변경되거나 언마운트될 때 cleanup 함수가 실행
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

App.js

import { useState } from 'react';
import Info from './hook/Info';

function App() {
  const [visible, setVisible] = useState(true);
  const handlerClick = () => setVisible(!visible);
  return (
    <>
      <button onClick={handlerClick}>{ visible ? '숨기기' : '보이기' }</button>
      <br />
      { visible && <Info /> }
    </>  
  );
}
export default App;

Info.js => 언마운트 될때만 cleanup함수가 호출되도록 하고 싶으면 의존 배열에 빈 배열을 설정

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const handlerChangeName = e => setName(e.target.value);
    const handlerChangeNickname = e => setNickname(e.target.value);

    useEffect(() => {
        console.log('렌더링이 완료되었습니다.');
        console.log({ name, nickname });
        return () => console.log('cleanup', name);
    }, []);
    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" value={name} onChange={handlerChangeName}/></p>
                <p>별명: <input type="text" value={nickname} onChange={handlerChangeNickname}/></p>
            </div>
        </>
    );
}
export default Info;

3) useRef

: 함수형 컴포넌트에서 DOM 요소를 직접 제어하기 위해서 사용

 

더보기

- 숫자를 입력할 수 있는 입력창과 입력한 숫자를 등록하는 버튼을 제공

- 입력창에 숫자를 입력하면 입력한 숫자를 입력값에 출력

- 등록 버튼을 클릭하면 등록된 숫자들을 리스트에 출력하고 입력창에 포커스를 이동

Average.js

import { useState, useRef } from "react";

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

    const handlerChangeNumber = e => setNumber(e.target.value);
    const handlerButtonClick = e => {
        const newList = list.concat(number);
        setList(newList);

        setNumber('');
        inputElement.current.focus();		//current 잊지말기
    }

	useEffect(() => inputElement.current.focus(), []);		//마운트 될때마다 입력창에 포커스를 설정하도록 수정

    const inputElement = useRef(); 		//useRef 추가

    return (
        <>
            <div>
                등록된 숫자:
                <ul>
                    { list.map((num, idx) => <li key={idx}>{num}</li>) }
                </ul>
                <div>
                    <p>입력값: {number}</p>
                </div>
                <div>
                    <input ref={inputElement} type="number" value={number} onChange={handlerChangeNumber}/>
                    <button onClick={handlerButtonClick}>등록</button>
                </div>
            </div>
        </>
    );
};
export default Average;
728x90

'React' 카테고리의 다른 글

Axios - http -> https 변경 시 오류  (0) 2024.01.12
React - Flask - Mysql 연동  (1) 2023.10.28
React - Ref  (0) 2023.10.25
React - 이벤트 핸들링  (0) 2023.10.24
React - 상태변수 state / setState()  (0) 2023.10.23