情况一:非异步请求
第一步:创建切片slice
import { createSlice, configureStore } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
}
}
});
第二步:配置 store
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
});
第三步:在组件中使用
import { useSelector, useDispatch } from 'react-redux';
import { counterSlice } from './counterSlice.js';
function Counter() {
const count = useSelector(state => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button
onClick={() => dispatch(counterSlice.actions.increment())}
>
Increment
</button>
<span>{count}</span>
<button
onClick={() => dispatch(counterSlice.actions.decrement())}
>
Decrement
</button>
</div>
);
}
情况二:异步请求(createAsyncThunk)
第一步:创建createAsyncThunk
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const fetchUserById = createAsyncThunk(
'users/fetchById',
async (userId, { rejectWithValue }) => {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return await response.json();
} catch (error) {
return rejectWithValue(error.message);
}
}
);
第二步:创建slice
const userSlice = createSlice({
name: 'user',
initialState: {
data: null,
loading: false,
error: null
},
reducers: {
clearUser: (state) => {
state.data = null;
}
},
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(fetchUserById.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchUserById.rejected, (state, action) => {
state.loading = false;
state.error = action.payload;
});
}
});
第三步:在组件中使用
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchUserById } from './userSlice';
function UserProfile({ userId }) {
const dispatch = useDispatch();
const { data, loading, error } = useSelector(state => state.user);
useEffect(() => {
dispatch(fetchUserById(userId));
}, [dispatch, userId]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!data) return null;
return (
<div>
<h2>{data.name}</h2>
<p>{data.email}</p>
</div>
);
}
export default UserProfile;