npm i @reduxjs/toolkit react-redux
1、在redux/user.js中创建模块user。从@reduxjs/toolkit中引入createSlice创建模块片段,我们需要传入name、初始数据initialState、改state的reducers等。最后需要导出reducer和action。
代码如下:
import { createSlice } from '@reduxjs/toolkit'
const userSlice = createSlice({
name: 'user', //action.type和reducer的名字,表现在控制台的调试器上,一般与模块同名
//初始数据
initialState: {
age: 18
},
reducers: {
// reducers中存放用于修改state的方法
changeAge(state, action) {
state.age = action.payload //传过来的数据存放在action.payload上
}
}
})
export const { changeAge } = userSlice.actions //需要把action导出,dispatch需要
export default userSlice.reducer //导出reducer,用于创建Store
2、在redux/index.js中,引入configureStore用于创建Store,还需要引入user模块的reducer完成创建。代码如下:
import { configureStore } from '@reduxjs/toolkit'
import userReducer from './user'
const Store = configureStore({
reducer: {
user: userReducer //模块名:reducer
}
})
export default Store
3、在index.js中与之前一样,引入Provider,传入Store。
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import Store from './redux'
import { Provider } from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
// 将store传入context,这样任何组件都能访问Store,而不需要在组件中手动引入Store
)
在jsx文件中,dispatch的是前面user模块文件导出的action。代码如下:
import React from 'react'
import { changeAge } from './redux/user'
import { useDispatch, useSelector } from 'react-redux'
export function About() {
const dispatch = useDispatch()
const age = useSelector((state) => state.user.age)
function addAge() {
dispatch(changeAge(age + 1))
}
return (
年龄{age}
)
}
export default About
在redux/uset.js文件中,定义一个action方法用于修改state。在导出这个方法的后面,引入createAsyncThunk创建thunk方法。在这个方法的回调中会接收store,我们可以在请求到数据之后触发dispatch完成state的修改,具体代码如下:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
const userSlice = createSlice({
name: 'user', //action.type和reducer的名字,表现在控制台的调试器上,一般与模块同名
//初始数据
initialState: {
data: []
},
reducers: {
setData(state, { payload }) {
state.data = payload
}
}
})
export const { setData } = userSlice.actions //需要把action导出,dispatch需要
// 在导出action的下方定义thunk方法
export const getDataThunk = createAsyncThunk('user/getData', async (id, store) => {
let res = await fetch(`http://localhost:3000/data.txt?id=${id}`)
res = await res.json()
store.dispatch(setData(res))
})
export default userSlice.reducer //导出reducer,用于创建Store
使用就是正常的dispatch这个thunk
import { getDataThunk} from './redux/user'
await dispatch(getDataThunk()) //因为返回promise,我们可以await,这样就是同步的啦
另外的方法是先定义好thunk方法,然后在slice配置对象中使用extraReducers函数,函数接收builder,利用builder.addCase添加回调,完成对state的修改。
代码如下:【但是我觉得上面的写法更简单】
// 利用createAsyncThunk创建异步action,第一个参数是 'action名' ,第二个参数是回调用于请求接口,用promise返回数据
export const fetchUser = createAsyncThunk('fetchUser', async (userId) => {
let res = await fetch('http://123.207.32.32:8000/home/multidata')
res = await res.json()
return res
})
{
name:'user',
initialState:{//...},
reducer:{//...},
extraReducers: (builder) => {
builder
// .addCase(fetchUser.pending, (state) => {
// state.loading = true;
// })
.addCase(fetchUser.fulfilled, (state, action) => {
state.list = action.payload
})
// .addCase(fetchUser.rejected, (state, action) => {
// state.loading = false;
// state.error = action.payload;
// });
},
// 下面的写法有警告
/* extraReducers: {
[fetchUser.pending](state, action) {
// state.list = action.payload
// 做一些加载转圈的操作
console.log('pending');
},
[fetchUser.fulfilled](state, action) {
state.list = action.payload
},
[fetchUser.rejected](state, action) {
// state.list = action.payload
console.log('rejected');
}
} */
}
redux有关的知识暂时总结完毕。