Redux Toolkit
Setup
- Install packages
yarn add @reduxjs/toolkit
Slice
- Create actions and reducer by
createSlice
redux/common/index.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
data: null,
};
export const commonSlice = createSlice({
name: "common",
initialState,
reducers: {
setData: (state, action) => {
state.data = action.payload;
}
},
});
export const {
setData
} = commonSlice.actions;
export default commonSlice.reducer;
Store
- Create store and import reducers
redux/store.js
import { configureStore } from "@reduxjs/toolkit";
import common from "./common";
const store = configureStore({
reducer: {
common,
},
});
export default store;
- Wrapper components with store provider
import store from "../redux/store.js";
const ReduxProvider = ({ children }) => {
return <Provider store={store}>{children}</Provider>;
};
const App = ()=>{
return (
<ReduxProvider>
// something else...
</ReduxProvider>
);
}
AsyncThunk
- Fetch api in async Thunk
redux/common/getData.js
import { createAsyncThunk } from "@reduxjs/toolkit";
import { setError } from "@/redux/error";
const getDataAsyncThunk = createAsyncThunk(
"common/getData",
async (payload, { dispatch }) => {
try {
const res = await fetch(..., payload);
return res;
} catch (error) {
dispatch(setError(error));
}
},
);
export default getDownloadLicenseAsyncThunk;
- add thunk to reducers
import { createSlice } from "@reduxjs/toolkit";
import getDataAsyncThunk from "./getData";
const initialState = {
isLoading: false,
data: null,
};
export const commonSlice = createSlice({
name: "common",
initialState,
reducers: {
setData: (state, action) => {
state.data = action.payload;
}
},
extraReducers: (builder) => {
builder.addCase(getDataAsyncThunk.pending, (state) => {
state.isLoading = true;
});
builder.addCase(getDataAsyncThunk.fulfilled, (state, action) => {
state.isLoading = false;
state.data = action.payload.data;
});
builder.addCase(getDataAsyncThunk.rejected, (state) => {
state.isLoading = false;
});
},
});
export const {
setData,
getData,
} = {
...commonSlice.actions,
getData: getDataAsyncThunk,
};
export default commonSlice.reducer;
Usage
- With store
import { useEffect } from "react";
import store from "../redux/store.js";
import { setData } from "../redux/common";
const App = () => {
useEffect(() => {
store.dispatch(setData({}));
}, []);
return null;
}
- With hooks
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { getData } from "../redux/common";
const App = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(getData({}));
}, [dispatch]);
return null;
}