유저 정보 페이지를 서버와 통신해 리액트 쿼리로 데이터를 가져오고, 그 데이터를 리덕스 툴킷에 넣는 로직을 보여주겠다.
리덕스 툴킷은 클라이언트 UI 상태 데이터 관련, 리액트 쿼리는 서버 데이터 관련해서 분리한 점을 강조했다.
React, Next.JS 환경이다.
npm install react-redux @reduxjs/toolkit @tanstack/react-query
// clientSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
users: [],
};
const clientSlice = createSlice({
name: 'client',
initialState,
reducers: {
setUsers: (state, action) => {
state.users = action.payload;
},
},
});
export const { setUsers } = clientSlice.actions;
export default clientSlice.reducer;
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import UserList from './UserList';
import clientReducer from './clientSlice';
const store = configureStore({
reducer: {
client: clientReducer,
},
});
const App = () => {
return (
<Provider store={store}>
<UserList />
</Provider>
);
};
export default App;
// UserList.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useQuery } from 'react-query';
import { setUsers } from './clientSlice';
// fetch API 코드
const fetchUsers = async () => {
const response = await fetch('https://reqres.in/api/users?page=1');
if (!response.ok) {
throw new Error('Failed to fetch users');
}
const data = await response.json();
return data.data;
};
const UserList = () => {
const dispatch = useDispatch();
const users = useSelector((state) => state.client.users);
// 리액트쿼리 사용 예시: useQuery 및 다양한 Return 사용 가능
const { isLoading, isError, error } = useQuery('users', fetchUsers, {
// 성공 및 에러 핸들링
onSuccess: (data) => {
dispatch(setUsers(data));
},
onError: (error) => {
// 에러핸들링 등
},
});
if (isLoading) {
return <div>Loading...</div>;
}
if (isError) {
return <div>Error: {error}</div>;
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>
{user.first_name} {user.last_name}
</li>
))}
</ul>
);
};
export default UserList;
refetchOnWindowFocus, //default: true
refetchOnMount, //default: true
refetchOnReconnect, //default: true
staleTime, //default: 0
cacheTime, //default: 5분 (60 * 5 * 1000)
refetchOnWindowFocus
)refetchOnMount
)refetchOnReconnect
)React-Query 는 캐싱 된 데이터는 기본적으로 항상 stale 하다고 판단하며, stale 상태인 데이터를 Refetching!
설정으로도 stale, fresh 상태 조절 가능.
결국 서버 데이터를 패칭해 온 데이터를 캐싱했어도, 사용자가 화면을 바라보고 있을 때는 그 시점에 있어서 가장 최신의 데이터를 바라보고 있는 상황이며, 페이지가 전환이 되었을 경우에도 해당 데이터의 상태가 stale 하다고 판단하여 리패칭 하며, 페이지에서 어떤 이벤트가 발생했을 경우엔 개발자가 트리거를 심어줌으로 써 데이터를 리패칭 할 수 있음.
위와 같은 React-Query 의 컨셉으로 인해서 사용자는 항상 신선한 (fresh) 데이터를 바라볼 수 있음. 즉, 데이터 무결성을 방지함.