Javascript 如何访问Redux reducer中的状态?
我有一个reducer,为了计算新的状态,我需要来自操作的数据,以及来自不由这个reducer管理的状态部分的数据。具体来说,在我将在下面展示的reducer中,我需要访问Javascript 如何访问Redux reducer中的状态?,javascript,reactjs,redux,Javascript,Reactjs,Redux,我有一个reducer,为了计算新的状态,我需要来自操作的数据,以及来自不由这个reducer管理的状态部分的数据。具体来说,在我将在下面展示的reducer中,我需要访问accountDetails.stateOfResidenceId字段 initialState.js: export default { accountDetails: { stateOfResidenceId: '', accountType: '', account
accountDetails.stateOfResidenceId
字段
initialState.js:
export default {
accountDetails: {
stateOfResidenceId: '',
accountType: '',
accountNumber: '',
product: ''
},
forms: {
blueprints: [
]
}
};
import * as types from '../constants/actionTypes';
import objectAssign from 'object-assign';
import initialState from './initialState';
import formsHelper from '../utils/FormsHelper';
export default function formsReducer(state = initialState.forms, action) {
switch (action.type) {
case types.UPDATE_PRODUCT: {
//I NEED accountDetails.stateOfResidenceId HERE
console.log(state);
const formBlueprints = formsHelper.getFormsByProductId(action.product.id);
return objectAssign({}, state, {blueprints: formBlueprints});
}
default:
return state;
}
}
import { combineReducers } from 'redux';
import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';
const rootReducer = combineReducers({
accountDetails,
forms
});
export default rootReducer;
formsReducer.js:
export default {
accountDetails: {
stateOfResidenceId: '',
accountType: '',
accountNumber: '',
product: ''
},
forms: {
blueprints: [
]
}
};
import * as types from '../constants/actionTypes';
import objectAssign from 'object-assign';
import initialState from './initialState';
import formsHelper from '../utils/FormsHelper';
export default function formsReducer(state = initialState.forms, action) {
switch (action.type) {
case types.UPDATE_PRODUCT: {
//I NEED accountDetails.stateOfResidenceId HERE
console.log(state);
const formBlueprints = formsHelper.getFormsByProductId(action.product.id);
return objectAssign({}, state, {blueprints: formBlueprints});
}
default:
return state;
}
}
import { combineReducers } from 'redux';
import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';
const rootReducer = combineReducers({
accountDetails,
forms
});
export default rootReducer;
index.js(根减速器):
export default {
accountDetails: {
stateOfResidenceId: '',
accountType: '',
accountNumber: '',
product: ''
},
forms: {
blueprints: [
]
}
};
import * as types from '../constants/actionTypes';
import objectAssign from 'object-assign';
import initialState from './initialState';
import formsHelper from '../utils/FormsHelper';
export default function formsReducer(state = initialState.forms, action) {
switch (action.type) {
case types.UPDATE_PRODUCT: {
//I NEED accountDetails.stateOfResidenceId HERE
console.log(state);
const formBlueprints = formsHelper.getFormsByProductId(action.product.id);
return objectAssign({}, state, {blueprints: formBlueprints});
}
default:
return state;
}
}
import { combineReducers } from 'redux';
import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';
const rootReducer = combineReducers({
accountDetails,
forms
});
export default rootReducer;
如何访问此字段?在分派操作时,可以传递参数。在这种情况下,您可以将
accountDetails.stateOfResidenceId
传递给操作,然后将其作为有效负载传递给减速器。您的选项是,除了使用组合减速器之外,还可以编写更多逻辑,或者在操作中包含更多数据。Redux常见问题解答涵盖以下主题:
此外,我目前正在为Redux文档编写一组新的页面,主题是“结构化减缩器”,您可能会发现这很有帮助。当前WIP页面位于。我建议您将其传递给动作创建者。
因此,在某个地方,您将有一个动作创建者,它可以执行以下操作:
updateProduct(arg1, arg2, stateOfResidenceId) {
return {
type: UPDATE_PRODUCT,
stateOfResidenceId
}
}
在触发动作的地方,假设您正在使用react,则可以使用
function mapStateToProps(state, ownProps) {
return {
stateOfResidenceId: state.accountdetails.stateOfResidenceId
}
}
并使用react redux的connect连接到react组件
connect(mapStateToProps)(YourReactComponent);
现在,在触发action updateProduct的react组件中,应该将stateOfResidenceId作为一个道具,并可以将其传递给action创建者
这听起来很复杂,但实际上是关于关注点的分离 我将使用以下示例:
export function updateProduct(product) {
return (dispatch, getState) => {
const { accountDetails } = getState();
dispatch({
type: UPDATE_PRODUCT,
stateOfResidenceId: accountDetails.stateOfResidenceId,
product,
});
};
}
基本上,您可以获得动作所需的所有数据,然后将这些数据发送到减速器。您可以尝试使用:
它允许您在代码中的任何位置获取状态,如下所示:
const localState1 = getState(reducerA.state1)
const localState2 = getState(reducerB.state2)
但是,首先考虑是否最好将外部状态作为有效负载传递到操作中 我不确定这种方法是否是反模式的,但它对我有效。在动作中使用curried函数
export const myAction = (actionData) => (dispatch, getState) => {
dispatch({
type: 'SOME_ACTION_TYPE',
data: actionData,
state: getState()
});
}
编写自己的组合函数非常简单,它可以完全满足您的需要:
import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';
const rootReducer = (state, action) => {
const newState = {};
newState.accountDetails = accountDetails(state.accountDetails, action);
newState.forms = forms(state.forms, action, state.accountDetails);
return newState;
};
export default rootReducer;
您的FormReducer将是:
export default function formsReducer(state = initialState.forms, action, accountDetails) {
formsReducer现在可以访问accountDetails
这种方法的好处是,您只公开所需的状态片段,而不是整个状态。如果您使用react-redux,并且只需要在一个位置执行该操作,或者您可以创建一个HOC(更高阶组件,不需要真正理解重要的是这可能会使html膨胀)需要访问的任何地方都要使用传递给操作的附加参数:
const-mapState=({accountDetails:{stateOfResidenceId}})=>stateOfResidenceId;
常量映射分派=(分派)=>({
pureUpdateProduct:(stateOfResidenceId)=>dispatch({type:types.UPDATE_PRODUCT,payload:stateOfResidenceId})
});
const mergeProps=(stateOfResidenceId,{pureUpdateProduct})=>({hydratedUpdateProduct:()=>pureUpdateProduct(stateOfResidenceId)});
const addHydratedUpdateProduct=connect(mapState、mapDispatch、mergeProps)
导出默认的AddHydreatedUpdateProduct(组件);
导出常量OtherHydreatedComponent=AddHydreatedUpdateProduct(OtherComponent)
当您使用mergeProps时,返回的内容将添加到props中,mapState和mapDispatch将仅用于提供mergeProps的参数。因此,换句话说,此函数会将其添加到组件props中(typescript语法):
(请注意,函数实际上返回操作本身,而不是void,但在大多数情况下,您将忽略这一点)
但你能做的是:
constmapstate=({accountDetails})=>accountDetails;
常量映射分派=(分派)=>({
pureUpdateProduct:(stateOfResidenceId)=>dispatch({type:types.UPDATE_PRODUCT,payload:stateOfResidenceId})
其他操作:(参数)=>调度(其他操作(参数))
});
const mergeProps=({stateOfResidenceId,…passAlong},{pureUpdateProduct,…otherActions})=>({
…很长时间,
……其他行动,
水合更新产品:()=>pureUpdateProduct(stateOfResidenceId),
});
const reduxPropsIncludingHydreatedAction=connect(映射状态、映射分派、合并Props)
导出默认ReduxPropsInIncludingHydreatedAction(ReactComponent);
这将为道具提供以下内容:
{
hydratedUpdateProduct: () => void,
otherAction: (param) => void,
accountType: string,
accountNumber: string,
product: string,
}
总的来说,尽管redux维护人员对扩展其软件包的功能进行了彻底的解约,以一种良好的方式将这些愿望包括在内,这将在不支持生态系统碎片化的情况下为这些功能创建一种模式,但令人印象深刻
像Vuex这样不那么顽固的软件包不会因为人们滥用反模式而产生太多问题,因为它们会丢失,同时支持一种比你用redux和最好的支持软件包存档时更简洁的语法和更少的样板文件。尽管软件包更加通用,但documantation更容易撤销因为他们不会像Redux文档那样在细节中迷失方向。如果您可以访问存储
,那么您应该使用store.getState()
这句话毫无意义。减速器功能的关键在于你根据当前状态和行动做出决策。感谢你的回答。我已经探索了你链接的一些资源,并将继续这样做。不过,我想问你一个问题,因为你似乎很有知识。另一个答案建议e使用thunk
。你认为这是解决我问题的好办法吗?如果这会把我的代码弄得一团糟或者不是一个最佳做法,这不是我想要追求的解决办法,但我觉得我没有足够的知识来确定这些选择的长期影响。是的,thunk是管理副作用的标准基本方法s和执行复杂逻辑