-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation
Description
프론트엔드 redux 가이드
1. 새로운 Redux Slice 생성
-
Slice 파일 생성:
redux디렉터리 안에 새로운 slice 파일을 생성합니다. 예: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에 리듀서 추가:redux/storeConfig.js파일에 새로 생성한 slice 리듀서를 추가합니다.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;
2. 사용자 정의 Hook 생성
-
Custom Hook 파일 생성:
redux디렉터리 안에 Custom Hook 파일을 생성합니다. 예: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;
3. API 클라이언트 설정 (옵션)
API 요청이 필요한 경우, redux/apiClient.js 파일에 API 클라이언트를 추가하고 사용합니다.
// 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;
};새로운 기능 추가 시 체크리스트:
- 새로운 slice를 생성하고 필요한 비동기 작업(
createAsyncThunk)을 정의했는가? - slice 파일에서 초기 상태와 리듀서, extraReducers를 정의했는가?
- 새로 생성한 slice를
storeConfig.js에 추가했는가? - 필요한 경우 Custom Hook 파일을 생성하고, 해당 Hook에서 상태를 반환하도록 설정했는가?
- 컴포넌트에서 Custom Hook을 사용하여 상태를 관리했는가?
- API 요청 시 올바른 엔드포인트와 헤더 설정을 확인했는가?
Originally posted by @Hello-LSY in #28 (comment)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation