我是React的新手。我正在尝试在受控组件中实现级联下拉列表。
父级下拉列表:
<select id="Regions" className="validate" value={this.state.userRegionId} onChange={this.handleRegionChange}>
{this.handleGetRegions()}
</select>
使用handleGetRegions()
装入组件时,componentDidMount
会填充父下拉列表。
onChange
处理程序handleRegionChange()
基本上根据所选值设置state
变量userRegionId
。
handleRegionChange(event){
this.setState({userRegionId: event.target.value});
}
随着state
值的更新,我使用componentDidUpdate
填充子下拉列表。我之所以使用componentDidUpdate
是因为state
是异步更新的,并且立即值仅在此处可用。
componentDidUpdate(){
this.handleGetCountriesByRegion(this.state.userRegionId);
}
handleGetCountriesByRegion
实现:
handleGetCountriesByRegion(regionId){
let regioncountryJSON = JSON.parse(locale["snclregioncountry-" + this.state.lang]);
let countriesJSON = regioncountryJSON[regionId] != undefined ? regioncountryJSON[regionId].Countries : undefined;
if (countriesJSON != undefined && countriesJSON.length > 0) {
let countries = [];
let defaultValue = locale["ddlCountry-" + this.state.lang];
countries.push(<option selected disabled key={-1} value={defaultValue}>{defaultValue}</option>);
countriesJSON.map((val) => {
countries.push(<option key={val.id} value={val.id}>{val.name}</option>)
});
return countries;
}
}
最后,我将handleGetCountriesByRegion
用作options
,这样子下拉菜单就会这样:
<select id="Countries" value={this.state.userCountry} onChange={this.handleCountryChange}>
{this.handleGetCountriesByRegion(this.state.userRegionId)}
</select>
它工作正常,但问题是handleGetCountriesByRegion
似乎被调用了两次。如何确保此函数仅被调用一次?另外,我想知道这是否是正确的方法。
答案 0 :(得分:0)
您的componentDidUpdate()两次被调用,原因是每次更新组件时都会调用componentDidUpdate(),此后才调用您的函数。解决方案是将以前的状态与新的状态进行比较,如下所示:-
componentDidUpdate(prevProps, prevState) {
if(this.state.userRegionId != prevState.userRegionId) {
this.handleGetCountriesByRegion(this.state.userRegionId);
}
}
答案 1 :(得分:0)
handleGetCountriesByRegion
被调用两次的原因是因为您在每次状态更新和DOM中都使用它:
componentDidUpdate(){
this.handleGetCountriesByRegion(this.state.userRegionId); <--- here
}
<select id="Countries" value={this.state.userCountry} onChange={this.handleCountryChange}>
{this.handleGetCountriesByRegion(this.state.userRegionId)} <--- and here
</select>
您的结构很好,但是请考虑将handleGetCountriesByRegion
重构为一个组件,该组件接收ID作为道具并根据其更改UI。