带有钩子的 React 和 Redux
React and Redux with hooks
好久没用 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 概念。
您在 switch/case
语句中利用 action.type
值,以便您可以仅分支和更新您需要的内容: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-extrareducers-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} }
在他们的示例中,他们更新了计数器(单个 属性)状态,并更新了用户(对象 属性)状态。
好久没用 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 概念。
您在 switch/case
语句中利用 action.type
值,以便您可以仅分支和更新您需要的内容: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-extrareducers-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} }
在他们的示例中,他们更新了计数器(单个 属性)状态,并更新了用户(对象 属性)状态。