所以我有一个具有这种基本结构的redux商店:
{
user: {
id: 1,
currentCompanyId: 2,
}
companyDetails: {
id: 2,
name: 'Joes Company'
},
otherCompanies: [2,3,4],
}
我有一个父页面,它在标题中有一个下拉列表,允许用户链接/切换到另一家公司。
父组件需要知道选择了哪家公司,以便在标题中显示名称。
子组件显示当前公司的详细信息。
将会有各种类型的公司,每种类型的网址/部分都会有所不同。因此,在子组件中,我试图设置用户的公司,然后加载该公司的详细信息。
子组件不需要直接引用用户或当前公司。
所以我正在做的是在我将在willmount
和willreceiveprops
中监听的子组件中更改网址,然后触发更新用户公司的操作。这将导致父级在用户对象发生更改时重新呈现。这反过来将创建一个新的/重新安装子组件。到目前为止,这似乎是合乎逻辑的。
问题在于,当我选择公司2并尝试切换到公司3时,它会将公司设置为3,然后再将其重置为2。
我不确定这是否与未更新的网址有关。我已经走了很多圈子,现在我不知道工作流程应该是什么了。
修改
如果我在this.loadContractorInfo(contractorId);
的{{1}}中注明ContractorHome.js
它将正常工作(即网址与链接中的数字保持一致,而不是旧版本。我认为这是与redux操作有关的是async,虽然我没有进行任何网络调用,但在获取承包商页面的数据和想要显示/更新当前公司的componentWillMount()
之间存在竞争条件
编辑2
所以要确认一下。我已经将网页加载到网站的根目录,一切都很好。我从下拉列表中选择了一家公司/承包商。这很好。我会从下拉列表中将该选择更改为其他承包商。要命中的第一个组件是父(contextheader),nextprops中的contextheader
prop将更新为在URL中具有正确的ID。此时的方法执行不会更新任何内容,也不会触发任何操作。然后它击中了孩子(contractorhome)willreceiveprops方法,再次在位置的URL是好匹配params。我已经在willrecieveprops中注释掉了所有代码,因此它也没有做任何事情。然后它将返回到父遗嘱道具,并且该位置将返回到URL中的先前ID。
location
摘录:
app.js
render() {
return (
<div className="app">
<Router>
<div>
<div className="bodyContent">
<ContextHeader />
<Switch>
{/* Public Routes */}
<Route path="/" exact component={HomePage} />
<Route path="/contractor" component={ContractorRoute} />
<Route path="/building" component={BuildingRoute} />
</Switch>
</div>
<Footer />
</div>
</Router>
</div>
);
}
:
contextheader
componentWillReceiveProps(nextProps) {
const { setCompany } = this.props;
const currentInfo = this.props.sharedInfo && this.props.sharedInfo.currentCompany;
const newInfo = nextProps.sharedInfo && nextProps.sharedInfo.currentCompany;
if (newInfo && newInfo.id && (!currentInfo || currentInfo.id !== newInfo.id)) {
setCompany(newInfo.id, newInfo.type);
}
}
render() {
const { user, companies, notifications } = this.props;
/* render things here */
}
);
}
}
const mapStateToProps = state => ({
user: state.user,
sharedInfo: state.sharedInfo,
companies: state.companies,
notifications: state.notifications,
});
const mapDispatchToProps = dispatch => ({
setCompany: (companyId, type) => dispatch(setCurrentCompany(companyId, type)),
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ContextHeader));
:
contractorRoute
const ContractorRoute = ({ match }) => (
<Switch>
<Route path={`${match.path}/:contractorId`} component={ContractorHome} />
</Switch>
);
contractorHome