reactjs - 带有钩子的 React 和 Redux
问题描述
很久没有 Redux 了,我开始生锈了。
我记得我们有 reducer 和所有应用程序状态管理的日子。
现在真的很难理解工作流程。
所以我有我的商店。
import { configureStore } from '@reduxjs/toolkit'
import userReducer from "../features/user";
export default configureStore({
reducer: {
user: userReducer
},
})
这就是所谓的切片?
import {createSlice} from "@reduxjs/toolkit";
export const rootSlice = createSlice({
name: "user",
initialState: {
value: {
person_in: null,
code: null,
surname: null,
name: null,
active: null,
token: null,
org_unit: null,
available_days: null,
current_available_days: null,
total_days: null,
is_logged_in: false,
}
},
reducers: {
updateUser: (state, action) => {
state.value = action.payload
}
}
});
export const { updateUser } = rootSlice.actions;
export default rootSlice.reducer;
所以我明白了,如果我想更新我去的用户的状态
dispatch(updateUser({...});
我怎样才能只更新code
属性或任何其他属性?
解决方案
为了实现更新初始状态对象的单个属性的能力,您还需要实现Action
类型的 redux 概念。
您可以利用语句中的action.type
值,switch/case
以便您可以仅分支和更新您需要的内容: https ://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers#handling-additional-actions 。
我不太熟悉,reduxjs/toolkit
但看起来他们createSlice
以稍微不同但非常直观的方式提供了这个: https ://redux-toolkit.js.org/api/createSlice#the-extrareduces-builder-callback-notation 。在其中将extraReducers
函数属性添加到createSlice
对象。
这是他们的示例代码:
import { createSlice, createAction } from '@reduxjs/toolkit'
import { createStore, combineReducers } from 'redux'
const incrementBy = createAction('incrementBy')
const decrementBy = createAction('decrementBy')
const counter = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: (state) => state + 1,
decrement: (state) => state - 1,
multiply: {
reducer: (state, action) => state * action.payload,
prepare: (value) => ({ payload: value || 2 }), // fallback if the payload is a falsy value
},
},
// "builder callback API", recommended for TypeScript users
extraReducers: (builder) => {
builder.addCase(incrementBy, (state, action) => {
return state + action.payload
})
builder.addCase(decrementBy, (state, action) => {
return state - action.payload
})
},
})
const user = createSlice({
name: 'user',
initialState: { name: '', age: 20 },
reducers: {
setUserName: (state, action) => {
state.name = action.payload // mutate the state all you want with immer
},
},
// "map object API"
extraReducers: {
[counter.actions.increment]: (
state,
action /* action will be inferred as "any", as the map notation does not contain type information */
) => {
state.age += 1
},
},
})
const reducer = combineReducers({
counter: counter.reducer,
user: user.reducer,
})
const store = createStore(reducer)
store.dispatch(counter.actions.increment())
// -> { counter: 1, user: {name : '', age: 21} }
store.dispatch(counter.actions.increment())
// -> { counter: 2, user: {name: '', age: 22} }
store.dispatch(counter.actions.multiply(3))
// -> { counter: 6, user: {name: '', age: 22} }
store.dispatch(counter.actions.multiply())
// -> { counter: 12, user: {name: '', age: 22} }
console.log(`${counter.actions.decrement}`)
// -> "counter/decrement"
store.dispatch(user.actions.setUserName('eric'))
// -> { counter: 12, user: { name: 'eric', age: 22} }
在他们的示例中,他们更新了计数器(单个属性)状态,并更新了用户(对象属性)状态。
推荐阅读
- php - 使用 eloquent 获取表模式,获取数组到字符串的转换错误
- angular - 如何在 Angular mono repo 中使用独立库?
- android - Android控制视图可见性,我得到错误
- vue.js - 通过迭代创建菜单时出现问题
- sftp - 如何克服批处理文件中的键盘交互式身份验证提示以将文件传输到 SFTP 服务器
- azure - Azure AD 与 Azure DevOps 同步
- swift - 从 UILabel 打开两个 url
- mouse - Turbo C++ 中的鼠标接口
- javascript - 用于 Google 电子表格中 Doubleklick 的 VBA 到 Java 转换
- bash - 如何仅使用 bash(无编辑器)创建 Kubernetes YAML 部署对象?