본문 바로가기

React/API 연동

[React] #3 | useReducer로 요청 상태 관리

#2 에서의 useState 대신에, useReducer를 사용하여 구현을 해보자

 

useReducer을 사용하여 LOADING, SUCESS, ERROR 액션에 따라 다르게 처리하기

 

 


 

Users.js

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

function reducer(state, action){
    switch(action.type){
        case 'LOADING':
            return{
                loading: true,
                data: null,
                error: null
            };
        case 'SUCCESS':
            return{
                loading: false,
                data: action.data,
                error: null
            };
        case 'ERROR':
            return{
                loading: false,
                data: null,
                error: action.error
            };
        default:
            throw new Error('Unhandled action type: ${action.type}')
    }
}

function Users() {

    const [state, dispatch] = useReducer(reducer, {
        loading: false,
        data: null,
        error: null
    });


    const fetchUsers = async()=>{
        dispatch({type: 'LOADING'});
        try{
            const response = await axios.get(
                'api 주소'
            );
            dispatch({type: 'SUCEESS', data: response.data});
        } catch (e) {
            dispatch({type: 'ERROR', error: e});
        }
    };

    useEffect(()=>{
        fetchUsers();
    },[]);

    const {loading, data: users, error} = state //state.data를 users 키워드로 조회

    if (loading) return <div>로딩중..</div>     // 로딩이 활성화되었을 때
    if (error) return <div>에러가 발생했습니다.</div>
    if (!users) return null;    //user 값이 아직 없을 때

    return (
        <ul>
            {users.map(user=>{
                <li key={user.id}>
                    {user.username} ({user.name});
                </li>
            })}
        </ul>
    )
}

export default Users

 

useReducer로 구현했을 때의 장점

  • useState의 setState함수를 여러번 사용하지 않아도 된다.
  • 리듀서로 로직을 분리했으니 다른곳에서도 쉽게 재사용가능

 

다음 포스팅 내용

  • 이번 포스팅에서 만든 reducer을 기반으로, 커스텀 Hook 만들기

 


Reference

벨로퍼트의 모던 리액트