React Redux实战
# 工具
Redux Toolkit (opens new window)
yarn add @reduxjs/toolkit react-redux
1
# 流程
useSelector
获取store
数据useDispatch
获取dispatch方法- 执行
store
模块中到处的actionCreate方法得到action对象
使用Redux Toolkit 创建counterStore
// counterStore import {createSlice} from "@reduxjs/toolkit"; const counterStore = createSlice({ name: 'counter', // 初始化状态 initialState: { value: 0 }, // 修改状态的方法 同步方法 支持直接修改 reducers: { increment: (state) => { state.value += 1 }, decrement: (state) => { state.value -= 1 } } }) // 解构出来actionCreate函数 const {increment, decrement} = counterStore.actions // 获取reducer const counterReducer = counterStore.reducer // 以按需导出的方式导出actionCreate export {increment, decrement} // 以默认导出的方式到处reducer export default counterReducer // index.js import {configureStore} from "@reduxjs/toolkit"; // 导入子模块reducer import counterReducer from "./modules/counterStore"; const store = configureStore({ reducer: { counter: counterReducer } }) export default store
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41为React注入store(进行连接操作)
内置provider组件,通过store参数把创建好的store实例注入应用
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import store from "./store"; import {Provider} from "react-redux"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <App/> </Provider> </React.StrictMode> ); reportWebVitals();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18使用store中的数据
使用钩子函数
useSelector
,作用是把store中的数据映射到组件import {useDispatch, useSelector} from "react-redux"; // 导入创建action对象的方法 import {addToNumber, decrement, increment} from "./store/modules/counterStore"; function App() { const counter = useSelector(state => state.counter.value); // 使用useDispatch方法 const dispatch = useDispatch(); return ( <div className="App"> counter:{counter} </div> ); } export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17修改store中的数据
使用hook函数
useDispatch
,作用生成提交action对象的dispatch函数import {useDispatch, useSelector} from "react-redux"; // 导入创建action对象的方法 import {addToNumber, decrement, increment} from "./store/modules/counterStore"; function App() { const counter = useSelector(state => state.counter.value); // 使用useDispatch方法 const dispatch = useDispatch(); return ( <div className="App"> {/*调用dispatch提交的action对象*/} <button onClick={() => dispatch(increment())}>Increment</button> counter:{counter} <button onClick={() => dispatch(decrement())}>Decrement</button> </div> ); } export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20提交action传参
在reducer的同步方法中添加参数,调用actionCreater的时候传递参数,参数被传到action的payload属性
import {useDispatch, useSelector} from "react-redux"; import {addToNumber, decrement, increment} from "./store/modules/counterStore"; function App() { const counter = useSelector(state => state.counter.value); const dispatch = useDispatch(); return ( <div className="App"> <button onClick={() => dispatch(increment())}>Increment</button> counter:{counter} <button onClick={() => dispatch(decrement())}>Decrement</button> {/*提交action传参*/} <button onClick={() => dispatch(addToNumber(10))}>add to 10</button> <button onClick={() => dispatch(addToNumber(20))}>add to 20</button> </div> ); } export default App; // couterStore import {createSlice} from "@reduxjs/toolkit"; const counterStore = createSlice({ name: 'counter', // 初始化状态 initialState: { value: 0 }, // 修改状态的方法 同步方法 支持直接修改 reducers: { addToNumber: (state, action) => { state.value = action.payload } } }) // 解构出来actionCreate函数 const {increment, decrement, addToNumber} = counterStore.actions // 获取reducer const counterReducer = counterStore.reducer // 以按需导出的方式导出actionCreate export {increment, decrement, addToNumber} // 以默认导出的方式到处reducer export default counterReducer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 异步操作
- 创建store的写法保持不变,配置好同步修改状态的方法,新建
channelStore
- 单独封装一个函数,在函数内部return一个新函数,在新函数中
- 封装异步请求获取数据
- 调用同步actionCreater传入异步数据生成一个action对象,并使用dispatch提交
- 组件中dispatch的写法保持不变
// channelStore.js
import {createSlice} from "@reduxjs/toolkit";
import axios from "axios";
const channelSlice = createSlice({
name: 'channel',
initialState: {
channelList: [],
},
reducers: {
setChannels: (state, action) => {
state.channelList = action.payload
},
}
})
// action导出
export const {setChannels} = channelSlice.actions
// 异步请求
const fetchChannelList = () => {
return async (dispatch) => {
const res = await axios.get('http://geek.itheima.net/v1_0/channels')
// 使用dispatch提交action
dispatch(setChannels(res.data.data.channels))
}
}
export {fetchChannelList}
const reducer = channelSlice.reducer
export default reducer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
在store/index.js
// 导入子模块reducer
import {configureStore} from "@reduxjs/toolkit";
import channelReducer from "./modules/channelStore";
const store = configureStore({
reducer: {
channel: channelReducer
}
})
export default store
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
在App
使用
import {useDispatch, useSelector} from "react-redux";
import {useEffect} from "react";
// 导入创建action对象的方法
import {fetchChannelList} from "./store/modules/channelStore";
function App() {
const channelList = useSelector(state => state.channel.channelList);
// 使用useDispatch方法
const dispatch = useDispatch();
// 使用useEffect触发异步请求执行
useEffect(() => {
dispatch(fetchChannelList())
}, [dispatch]);
return (
<div className="App">
<ul>
{channelList.map(item => {
return <li key={item.id}>{item.name}</li>
})}
</ul>
</div>
);
}
export default App;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 写好store
- 先定义好同步修改的操作
- 再定义异步获取的部分
- 再根里面进行结合
- 使用中间件react-redux连接
- 注入store
- 触发action执行
- useDispatch
- actionCreater导入进来
- useEffect
- 获取渲染数据列表
- useSelector
- 渲染
# 基本例子
安装
yarn add @reduxjs/toolkit react-redux
创建
src/store/reducers/count.ts
和src/store/index.js
在
count
中import { createSlice } from "@reduxjs/toolkit"; export const countSlice = createSlice({ name: "count", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; } } }); export const { increment, decrement } = countSlice.actions; export default countSlice.reducer;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20在index.js
import { configureStore } from "@reduxjs/toolkit"; import countReducer from "./reducers/count"; export default configureStore({ reducer: { count: countReducer, }, });
1
2
3
4
5
6
7
8在
./index.js
/** * @format */ import { AppRegistry } from "react-native"; import App from "./App"; import { name as appName } from "./app.json"; import { Provider } from "react-redux"; import store from "./src/store"; const ProviderApp = () => (<Provider store={store}> <App /> </Provider>); AppRegistry.registerComponent(appName, () => ProviderApp);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16在
App
<Provider store={store}> <Routes /> </Provider>
1
2
3
上次更新: 2024/08/14, 04:14:33