从另一个 reducer 访问一个 reducer 状态
Accessing a reducer state from within another reducer
我有一个减速器,当一个动作被调度时,我会重新调整适当的状态。现在我定期调用 API,因此结果将一次又一次地触发一个动作。所以我想要的是,如果 reducer 状态已经有数据,那么在发送调用时另一个 reducer 不会将状态显示为正在加载。它必须仅在第一次接收数据时保持其加载状态。希望我能解释清楚
这是我的代码片段
加载状态减速器
const loading = (state = false, action) => {
switch (action.type) {
case 'GET_AUDIT_DATA': // here I want to return true only when there is no data available
return true
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
组合减速器
const allReducers = combineReducers({
auditData: AuditData,
auditLoading: AuditLoading,
modifiedOrders: ModifiedOrders
});
export default allReducers;
Reducer returning 超级代理触发的操作数据
const auditData = (state = [], action) => {
switch(action.type) {
case 'GET_AUDIT_DATA_RECEIVED':
console.log(action.data);
return action.data;
case 'GET_AUDIT_DATA_ERROR':
return action.err;
default :
return state;
}
}
export default auditData;
所以最初 auditData
不包含任何数据,只有在第一次成功调用它后 return 才包含数据。当它同时被调用时,loading state reducer
被调用,只有当审计数据缩减器不包含任何数据时,它应该 return 在 GET_AUDIT_DATA
操作中为真。
return 仅从 auditData
获取的当前数据也是正确的方法,否则我应该采取不同的方式。基本上我想 overwrite
current data
和 new one
.
最好的方法是向 Loading state reducer 发送一条信息,以了解其他 reducer 是否已经有数据。最后要有:
const loading = (state = false, action) => {
switch (action.type) {
case 'GET_AUDIT_DATA':
if(!action.dataAlreadyInitialized){
return true
}
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
您应该可以从操作函数访问应用程序状态并执行以下操作:
dispatch({
type:'GET_AUDIT_DATA',
dataAlreadyInitialized: appState.auditData.length > 0
});
您可以通过存储调用 getState()
以获取缩减器列表和缩减器内部的当前状态。
- 将
store
导入 auditLoading
(使用商店获取值。不要改变商店)
store.getState().auditLoading
会给你 auditLoading
reducer 的状态。
这种方法类似于redux-thunk
提供的回调。其中(dispatch, getState) => {}
会返回到action.
import store from '../../../redux/store'
console.log(store.getState().loginReducer.accessToken)
通过这条语句我们可以得到accessToken的状态
接受的答案很好(通过操作传递数据长度),但如果它是一条被广泛使用的信息,可能会变得费力。还有另一种解决方案,有时更适合像 'current user' 这样的东西,它可能被每个动作使用。
根据 Redux FAQ https://redux.js.org/faq/reducers 向 reducer 函数添加第三个参数是完全可以接受的。即:
加载状态减速器
const loading = (state = false, action, noData) => {
switch (action.type) {
case 'GET_AUDIT_DATA':
return noData
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
组合减速器
不幸的是,这意味着我们必须编写代码来组合 reducer,而不是使用 combineReducers 快捷方式。但这并不难,您只需调用每个 reducer 并在发生任何更改时创建一个新对象:
const allReducers = (state = null, action) => {
const auditData = AuditData(state?.auditData, action);
const auditLoading = AuditLoading(state?.auditLoading, action, !state?.auditData?.length);
const modifiedOrders = ModifiedOrders(state?.modifiedOrders, action);
return (auditData !== state?.auditData ||
auditLoading !== state?.auditLoading ||
modifiedOrders !== state?.modifiedOrders) ?
{ auditData, auditLoading, modifiedOrders } : state;
});
export default allReducers;
注意传递给 AuditLoading reducer 的第三个参数。不需要对其他 reducer 或调用该操作的代码进行任何更改。这很好!
我有一个减速器,当一个动作被调度时,我会重新调整适当的状态。现在我定期调用 API,因此结果将一次又一次地触发一个动作。所以我想要的是,如果 reducer 状态已经有数据,那么在发送调用时另一个 reducer 不会将状态显示为正在加载。它必须仅在第一次接收数据时保持其加载状态。希望我能解释清楚
这是我的代码片段
加载状态减速器
const loading = (state = false, action) => {
switch (action.type) {
case 'GET_AUDIT_DATA': // here I want to return true only when there is no data available
return true
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
组合减速器
const allReducers = combineReducers({
auditData: AuditData,
auditLoading: AuditLoading,
modifiedOrders: ModifiedOrders
});
export default allReducers;
Reducer returning 超级代理触发的操作数据
const auditData = (state = [], action) => {
switch(action.type) {
case 'GET_AUDIT_DATA_RECEIVED':
console.log(action.data);
return action.data;
case 'GET_AUDIT_DATA_ERROR':
return action.err;
default :
return state;
}
}
export default auditData;
所以最初 auditData
不包含任何数据,只有在第一次成功调用它后 return 才包含数据。当它同时被调用时,loading state reducer
被调用,只有当审计数据缩减器不包含任何数据时,它应该 return 在 GET_AUDIT_DATA
操作中为真。
return 仅从 auditData
获取的当前数据也是正确的方法,否则我应该采取不同的方式。基本上我想 overwrite
current data
和 new one
.
最好的方法是向 Loading state reducer 发送一条信息,以了解其他 reducer 是否已经有数据。最后要有:
const loading = (state = false, action) => {
switch (action.type) {
case 'GET_AUDIT_DATA':
if(!action.dataAlreadyInitialized){
return true
}
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
您应该可以从操作函数访问应用程序状态并执行以下操作:
dispatch({
type:'GET_AUDIT_DATA',
dataAlreadyInitialized: appState.auditData.length > 0
});
您可以通过存储调用 getState()
以获取缩减器列表和缩减器内部的当前状态。
- 将
store
导入auditLoading
(使用商店获取值。不要改变商店) store.getState().auditLoading
会给你auditLoading
reducer 的状态。
这种方法类似于redux-thunk
提供的回调。其中(dispatch, getState) => {}
会返回到action.
import store from '../../../redux/store'
console.log(store.getState().loginReducer.accessToken)
通过这条语句我们可以得到accessToken的状态
接受的答案很好(通过操作传递数据长度),但如果它是一条被广泛使用的信息,可能会变得费力。还有另一种解决方案,有时更适合像 'current user' 这样的东西,它可能被每个动作使用。
根据 Redux FAQ https://redux.js.org/faq/reducers 向 reducer 函数添加第三个参数是完全可以接受的。即:
加载状态减速器
const loading = (state = false, action, noData) => {
switch (action.type) {
case 'GET_AUDIT_DATA':
return noData
case 'GET_AUDIT_DATA_RECEIVED':
return false
case 'GET_AUDIT_DATA_ERROR':
return false
default:
return state
}
}
组合减速器
不幸的是,这意味着我们必须编写代码来组合 reducer,而不是使用 combineReducers 快捷方式。但这并不难,您只需调用每个 reducer 并在发生任何更改时创建一个新对象:
const allReducers = (state = null, action) => {
const auditData = AuditData(state?.auditData, action);
const auditLoading = AuditLoading(state?.auditLoading, action, !state?.auditData?.length);
const modifiedOrders = ModifiedOrders(state?.modifiedOrders, action);
return (auditData !== state?.auditData ||
auditLoading !== state?.auditLoading ||
modifiedOrders !== state?.modifiedOrders) ?
{ auditData, auditLoading, modifiedOrders } : state;
});
export default allReducers;
注意传递给 AuditLoading reducer 的第三个参数。不需要对其他 reducer 或调用该操作的代码进行任何更改。这很好!