react reducx的使用
安装依赖
在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
});