useReducer 로 요청 상태 관리하기

이번에는 이전에 구현했던 User 컴포넌트에서 useState 대신에 useReducer 를 사용해서 구현을 해보도록 하겠다.

 

useReducer 를 사용하여 LOADING, SUCCESS, ERROR 액션에 따라 다르게 처리를 한다.

 

components/User.js

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

// LOADING, SUCCESS, ERROR 세가지 액션을 관리
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 User() {

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

    const fetchUsers = async () => {
        dispatch({ type: 'LOADING' }); // 페이지 시작시 LOADING 액션을 줌
        try {
            const response = await axios.get(
                'https://jsonplaceholder.typicode.com/users/'
            );
            dispatch({ type: 'SUCCESS', data: response.data }); // API 에서 데이터 조회된 뒤 SUCCESS 액션을 줌
        } catch (e) {
            dispatch({ type: 'ERROR', error: e }); // 에러가 날 시 EORROR 액션을 줌
        }
    }
   
    useEffect(() => {
        fetchUsers();
    }, []);

    const { loading, data: users, error } = state; // data를 users 키워드로 조회
   if (loading) return <div>로딩중..</div>
   if (error) return <div>에러가 발생 하였습니다.</div>
   if (!users) return null;

    return(
        <div>
            <ul>
                {users.map(user => (
                    <li key={user.id}>
                        {user.username} ({user.name})
                    </li>
                ))}
            </ul>
            <button onClick={fetchUsers}>다시 불러오기</button>
        </div>
    );
}

export default User;

위 코드와 같이 리듀서를 User 컴포넌트 밖에 만들어 준 뒤 어느 곳에서 액션을 줄 것인지 dispatch로 정해주면 된다.

useReducer 로 구현했을 때의 장점은 useState  setState 함수를 여러번 사용하지 않아도 된다는점과 리듀서로 로직을 분리했으니 다른곳에서도 쉽게 재사용을 할 수 있다는 점 이다.

 

App.js

import React from 'react';
import User from './components/users';


function App() {
    return <User/>;
}

export default App;

App.js에서 User컴포넌트를 불러와준다.

 

실행결과

useState로 구현 했을 때와 같이 잘 작동하는 것을 볼 수 있다.

+ Recent posts