Open Hello-LSY opened 1 month ago
프론트엔드 redux 가이드
Slice 파일 생성: redux 디렉터리 안에 새로운 slice 파일을 생성합니다. 예: redux/profileSlice.js.
redux
redux/profileSlice.js
Slice 구성: 아래의 기본 구조를 사용해 새로운 slice를 구성합니다.
// redux/profileSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import { getApiClient } from './apiClient'; // 예시 비동기 작업 (프로필 데이터 가져오기) export const fetchProfile = createAsyncThunk( 'profile/fetchProfile', async (memberId, { getState, rejectWithValue }) => { const token = getState().auth.token; try { const apiClient = getApiClient(token); const response = await apiClient.get(`/api/profiles/${memberId}`); return response.data; } catch (error) { return rejectWithValue(error.response ? error.response.data : 'Network error'); } } ); const profileSlice = createSlice({ name: 'profile', initialState: { profileData: null, loading: false, error: null, }, reducers: { clearProfile: (state) => { state.profileData = null; state.error = null; }, }, extraReducers: (builder) => { builder .addCase(fetchProfile.pending, (state) => { state.loading = true; state.error = null; }) .addCase(fetchProfile.fulfilled, (state, action) => { state.loading = false; state.profileData = action.payload; }) .addCase(fetchProfile.rejected, (state, action) => { state.loading = false; state.error = action.payload || 'Failed to fetch profile data'; }); }, }); export const { clearProfile } = profileSlice.actions; export default profileSlice.reducer;
storeConfig.js에 리듀서 추가:
storeConfig.js
redux/storeConfig.js 파일에 새로 생성한 slice 리듀서를 추가합니다.
redux/storeConfig.js
import { configureStore } from '@reduxjs/toolkit'; import authReducer from './authSlice'; import businessCardReducer from './businessCardSlice'; import profileReducer from './profileSlice'; // 새 slice 추가 const storeConfig = configureStore({ reducer: { auth: authReducer, businessCard: businessCardReducer, profile: profileReducer, // 새 리듀서 등록 }, }); export default storeConfig;
Custom Hook 파일 생성: redux 디렉터리 안에 Custom Hook 파일을 생성합니다. 예: redux/profileState.js.
redux/profileState.js
Hook 구성:
// redux/profileState.js import { useSelector, useDispatch } from 'react-redux'; import { fetchProfile, clearProfile } from './profileSlice'; export const useProfile = () => { const profile = useSelector((state) => state.profile); const dispatch = useDispatch(); const fetchUserProfile = (memberId) => { return dispatch(fetchProfile(memberId)); // return 추가 }; const clearUserProfile = () => { dispatch(clearProfile()); }; return { profile, fetchUserProfile, clearUserProfile, }; };
컴포넌트에서 Custom Hook 사용:
컴포넌트에서 Custom Hook을 사용하여 상태를 관리합니다.
// components/ProfileComponent.js import React, { useEffect } from 'react'; import { View, Text, ActivityIndicator } from 'react-native'; import { useProfile } from '../redux/profileState'; const ProfileComponent = ({ memberId }) => { const { profile, fetchUserProfile } = useProfile(); useEffect(() => { fetchUserProfile(memberId); }, [memberId]); if (profile.loading) { return <ActivityIndicator size="large" color="#0000ff" />; } if (profile.error) { return <Text>Error: {profile.error}</Text>; } return ( <View> {profile.profileData ? ( <Text>Profile Name: {profile.profileData.name}</Text> ) : ( <Text>No Profile Data</Text> )} </View> ); }; export default ProfileComponent;
API 요청이 필요한 경우, redux/apiClient.js 파일에 API 클라이언트를 추가하고 사용합니다.
redux/apiClient.js
// redux/apiClient.js import axios from 'axios'; const API_BASE_URL = '<http://10.0.2.2:8080>'; // API URL 설정 export const getApiClient = (token = '') => { const headers = { 'Content-Type': 'application/json', }; if (token) { headers.Authorization = `Bearer ${token}`; } const instance = axios.create({ baseURL: API_BASE_URL, headers, timeout: 5000, }); instance.interceptors.request.use( (config) => { console.log('Request Config:', config); return config; }, (error) => { console.error('Request Error:', error); return Promise.reject(error); } ); instance.interceptors.response.use( (response) => { console.log('Response Data:', response.data); return response; }, (error) => { if (error.response) { console.error('Server Error:', error.response.data); } else if (error.request) { console.error('No Response from Server:', error.request); } else { console.error('Request Setup Error:', error.message); } return Promise.reject(error); } ); return instance; };
새로운 기능 추가 시 체크리스트:
createAsyncThunk
Originally posted by @Hello-LSY in https://github.com/Hello-LSY/Baenang/issues/28#issuecomment-2385675831
1. 새로운 Redux Slice 생성
Slice 파일 생성:
redux
디렉터리 안에 새로운 slice 파일을 생성합니다. 예:redux/profileSlice.js
.Slice 구성: 아래의 기본 구조를 사용해 새로운 slice를 구성합니다.
storeConfig.js
에 리듀서 추가:redux/storeConfig.js
파일에 새로 생성한 slice 리듀서를 추가합니다.2. 사용자 정의 Hook 생성
Custom Hook 파일 생성:
redux
디렉터리 안에 Custom Hook 파일을 생성합니다. 예:redux/profileState.js
.Hook 구성:
컴포넌트에서 Custom Hook 사용:
컴포넌트에서 Custom Hook을 사용하여 상태를 관리합니다.
3. API 클라이언트 설정 (옵션)
API 요청이 필요한 경우,
redux/apiClient.js
파일에 API 클라이언트를 추가하고 사용합니다.새로운 기능 추가 시 체크리스트:
createAsyncThunk
)을 정의했는가?storeConfig.js
에 추가했는가?Originally posted by @Hello-LSY in https://github.com/Hello-LSY/Baenang/issues/28#issuecomment-2385675831