네, 맞습니다. 리덕스 툴킷에서는 slice를 사용하여 리듀서와 액션들을 함께 관리합니다. slice는 리덕스 스토어에 필요한 모든 것을 포함하는 논리적인 모듈입니다. slice를 사용하면 액션 생성자와 리듀서를 한 곳에 모을 수 있으므로 코드의 구조화와 유지보수가 용이해집니다.
로그인 관리의 경우, createSlice 함수를 사용하여 slice를 생성하고, 그 안에 액션 및 리듀서를 정의할 수 있습니다. 아래는 slice를 활용한 방법입니다.
// authSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { AppThunk, RootState } from './store';
interface User {
username: string;
// other user fields...
}
interface AuthState {
user: User | null;
loading: boolean;
error: string | null;
}
const initialState: AuthState = {
user: null,
loading: false,
error: null,
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
loginRequest(state) {
state.loading = true;
state.error = null;
},
loginSuccess(state, action: PayloadAction<User>) {
state.loading = false;
state.user = action.payload;
},
loginFailure(state, action: PayloadAction<string>) {
state.loading = false;
state.error = action.payload;
},
logout(state) {
state.user = null;
},
},
});
export const { loginRequest, loginSuccess, loginFailure, logout } = authSlice.actions;
export default authSlice.reducer;
// 액션 생성자와 리듀서를 slice 내에서 정의하고, 해당 액션들을 바로 가져다 사용할 수 있습니다.
이제 스토어 설정은 이전과 동일하게 합니다. 그러나 스토어 상태에 해당 슬라이스를 추가해야 합니다.
// store.ts
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';
const store = configureStore({
reducer: {
auth: authReducer,
},
});
export default store;
// 스토어 설정은 slice로 생성한 리듀서를 사용하도록 합니다.
사용 방법은 이전과 동일합니다. useSelector로 슬라이스 상태를 가져오고, useDispatch로 액션을 디스패치합니다.
import { useDispatch, useSelector } from 'react-redux';
import { loginRequest, logout } from './authSlice';
import { RootState } from './store';
const YourComponent = () => {
const dispatch = useDispatch();
const authState = useSelector((state: RootState) => state.auth);
const handleLogin = () => {
dispatch(loginRequest());
// 실제 로그인 API 호출 등의 작업 수행
};
const handleLogout = () => {
dispatch(logout());
};
return (
<div>
{authState.user ? (
<>
<p>Welcome, {authState.user.username}</p>
<button onClick={handleLogout}>Logout</button>
</>
) : (
<button onClick={handleLogin}>Login</button>
)}
</div>
);
};
이것으로 리덕스 툴킷과 슬라이스를 사용하여 타입스크립트로 로그인 상태를 관리할 수 있습니다.
맞습니다. TypeScript에서는 RootState와 AppDispatch를 사용하여 리덕스 스토어의 상태 및 디스패치 함수의 타입을 정의하는 것이 좋습니다. 이를 통해 타입 안정성을 확보하고 코드를 더 잘 이해할 수 있습니다.
아래 코드에서 RootState는 스토어의 전체 상태를 나타내는 타입이고, AppDispatch는 액션을 디스패치하는 함수의 타입입니다.
// store.ts
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';
const store = configureStore({
reducer: {
auth: authReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
그리고 이를 사용하여 useSelector와 useDispatch를 타입 안전하게 사용할 수 있습니다.
import { useDispatch, useSelector } from 'react-redux';
import { loginRequest, logout } from './authSlice';
import { RootState, AppDispatch } from './store';
const YourComponent = () => {
const dispatch: AppDispatch = useDispatch();
const authState = useSelector((state: RootState) => state.auth);
const handleLogin = () => {
dispatch(loginRequest());
// 실제 로그인 API 호출 등의 작업 수행
};
const handleLogout = () => {
dispatch(logout());
};
return (
<div>
{authState.user ? (
<>
<p>Welcome, {authState.user.username}</p>
<button onClick={handleLogout}>Logout</button>
</>
) : (
<button onClick={handleLogin}>Login</button>
)}
</div>
);
};
이렇게 하면 useSelector 및 useDispatch를 사용할 때 타입 안정성이 제공되어 코드의 안정성과 가독성이 향상됩니다.