安装依赖
在React项目中,需要安装@reduxjs/toolkit
和react-redux
两个包:
npm install @reduxjs/toolkit react-redux
创建Redux相关文件
创建slice
使用
createSlice
创建slice,它会自动生成action creator和reducer。例如:import { createSlice } from '@reduxjs/toolkit'; const counterSlice = createSlice({ name: 'counter', initialState: { count: 0 }, reducers: { increment(state) { state.count++; }, decrement(state) { state.count--; }, addToNum(state, action) { state.count += action.payload; } } }); export const { increment, decrement, addToNum } = counterSlice.actions; export default counterSlice.reducer;
创建store
使用
configureStore
创建store,它会自动配置中间件和Redux DevTools:import { configureStore } from '@reduxjs/toolkit'; import counterReducer from './counterSlice'; const store = configureStore({ reducer: { counter: counterReducer } }); export default store;
在React应用中使用Redux
提供store
在React应用的顶层组件中,使用
<Provider>
组件将store提供给整个应用:import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import store from './store'; import App from './App'; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
在组件中使用Redux
在React组件中,可以使用
useSelector
和useDispatch
两个Hooks来读取state和分发actionimport React from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { increment, decrement, addToNum } from './counterSlice'; function Counter() { const count = useSelector(state => state.counter.count); const dispatch = useDispatch(); return ( <div> <p>Count: {count}</p> <button onClick={() => dispatch(increment())}>Increment</button> <button onClick={() => dispatch(decrement())}>Decrement</button> <button onClick={() => dispatch(addToNum(20))}>Add 20</button> </div> ); } export default Counter;
2. 创建异步Thunk
使用createAsyncThunk
创建一个异步Thunk,它会自动生成pending
、fulfilled
和rejected
的action类型。例如,假设你有一个API接口https://jsonplaceholder.typicode.com/users
,你想要获取用户数据并更新state:
// src/thunks/userThunks.js
import { createAsyncThunk } from '@reduxjs/toolkit';
export const fetchUserById = createAsyncThunk(
'users/fetchById',
async (userId) => {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
}
);
3. 创建Slice
在createSlice
中处理异步Thunk的pending
、fulfilled
和rejected
状态。你可以使用extraReducers
来监听这些状态并更新state:
// src/slices/userSlice.js
import { createSlice } from '@reduxjs/toolkit';
import { fetchUserById } from '../thunks/userThunks';
const initialState = {
user: null,
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchUserById.fulfilled, (state, action) => {
state.status = 'succeeded';
state.user = action.payload;
})
.addCase(fetchUserById.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
}
});
export default userSlice.reducer;
4. 创建Store
在store.js
中配置store,引入你的slice和Thunk:
// src/store.js
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';
export const store = configureStore({
reducer: {
user: userReducer
}
});
5. 在React组件中使用
在React组件中,你可以使用useDispatch
来触发异步Thunk,并使用useSelector
来读取state:
// src/components/UserComponent.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUserById } from '../thunks/userThunks';
function UserComponent() {
const dispatch = useDispatch();
const { user, status, error } = useSelector((state) => state.user);
const handleFetchUser = () => {
dispatch(fetchUserById(1)); // 假设用户ID为1
};
return (
<div>
<button onClick={handleFetchUser}>Fetch User</button>
{status === 'loading' && <p>Loading...</p>}
{status === 'succeeded' && (
<div>
<h2>User Details</h2>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
)}
{status === 'failed' && <p>Error: {error}</p>}
</div>
);
}
export default UserComponent;
6. 提供Store
确保在顶层组件中使用<Provider>
来提供store:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
2.多个reducer时, 使用combineReducers
组合reducer
在store.js
中,使用combineReducers
将多个reducer组合成一个根reducer,然后传递给store。
// src/store.js
import { configureStore, combineReducers } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';
import counterReducer from './slices/counterSlice';
const rootReducer = combineReducers({
user: userReducer,
counter: counterReducer
});
export const store = configureStore({
reducer: rootReducer
});