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
上次更新: 2023/11/11, 16:31:46