[英]onChange of <select> element in child component not re-rendering the parent state in React, Warning: unmounted component
我将状态从子级提升到父级,并尝试使用HTTP请求中的数据呈现选择元素。 Inv
子组件中的选择标记值将显示以前选择的值,但是出现此错误:
警告:无法在已卸载的组件上调用setState(或forceUpdate)。 这是空操作,但它表明应用程序中发生内存泄漏。 要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。
看起来错误来自Inv
子组件,该子组件正在使用this.state.identInvsData
传递给道具。 那是我唯一的错误。 else语句中未获得identInvsData
的子组件不会获得该错误消息。 父组件不会重新渲染或“装载”子组件。
关于我在做什么错的任何想法吗?
编辑:子组件正在从HTTP端点填充数据,但是onChange不会更改
setState
的值,只有当我选择按钮Add Inv
。 它添加了另一个孩子,但也允许以前的孩子进行更改。
身份父组件
class Identity extends React.Component {
state = {
invIds: [],
inTypes: [],
invSeqIds: [],
numChildren: 0,
addInvBtnPressed: false
};
handleAddInv = () => {
this.setState({
numChildren: this.state.numChildren + 1,
addInvBtnPressed: true
});
};
onChangeInv = (e, index, sId) => {
const invIdsArry = this.state.invIds;
const invSeqIdsArry = this.state.invSeqIds;
const newId = [
...invIdsArry.slice(0, index),
(invIdsArry[index] = e.target.value),
...invIdsArry.slice(index + 1)
];
if (sId) {
const newSeqId = [
...invSeqIdsArry.slice(0, index),
(invSeqIdsArry[index] = sId),
...invSeqIdsArry.slice(index + 1)
];
this.setState({ invIds: newId, invSeqIds: newSeqId });
} else {
this.setState({ invIds: newId });
}
};
onChangeType = (e, index) => {
const invTypesArry = this.state.invTypes;
const newTypes = [
...invTypesArry.slice(0, index),
(invTypesArry[index] = e.target.value),
...invTypesArry.slice(index + 1)
];
this.setState({ invTypes: newTypes });
};
render() {
const children = [];
var i;
if (this.state.identInvsData && !this.state.addInvBtnPressed) {
for (i = 0; i < this.state.numChildren; i += 1) {
children.push(
<Inv
key={i}
invKey={i}
onChangeInv={this.onChangeInv.bind(this)}
onChangeType={this.onChangeType.bind(this)}
invId={this.state.identInvsData[i].invId}
invType={this.state.identInvsData[i].invTypeCd}
seqId={this.state.identInvsData[i].seqId}
invData={this.state.identInvsData[i]}
/>
);
}
} else if (this.state.identInvsData && this.state.addInvBtnPressed) {
for (i = 0; i < this.state.numChildren; i += 1) {
children.push(
<Inv
key={i}
invKey={i}
onChangeInv={this.onChangeInv.bind(this)}
onChangeType={this.onChangeType.bind(this)}
/>
);
}
} else {
for (i = 0; i < this.state.numChildren; i += 1) {
children.push(
<Inv
key={i}
invKey={i}
onChangeInv={this.onChangeInv.bind(this)}
onChangeType={this.onChangeType.bind(this)}
/>
);
}
}
return (
<div>
<button
type="button"
className="btn btn-info"
onClick={this.handleAddInv}
>
Add Inv
</button>
<div>{children}</div>
</div>
)
}
}
export default Identity;
Inv子组件
class Inv extends React.Component {
state = {
kddLookupData: "",
invData: ""
};
componentDidMount = () => {
kddlookups_getAll().then(resp => {
this.setState({
kddLookupData: resp.data.item
});
});
invs_getAll().then(resp => {
this.setState({
invData: resp.data.items
});
});
};
handleInvestigatorChange = e => {
this.props.onChangeInv(e, this.props.invKey, this.props.seqId);
};
handleInvestigatorTypeChange = e => {
this.props.onChangeType(e, this.props.invKey);
};
render() {
return (
<div>
<select
value={this.props.invId}
name={this.props.invKey}
onChange={this.handleInvChange.bind(this)}
>
<option className="blank">Select inv name:</option>
{this.state.invData &&
this.state.invData.map(inv => {
return (
<option key={inv.userId} value={inv.userId}>
{inv.invName}
</option>
);
})}
</select>
<select
value={this.props.invType}
name={this.props.invKey}
onChange={this.handleInvTypeChange.bind(this)}
>
<option className="blank">Select inv type:</option>
{this.state.kddData &&
this.state.kddData.kdd_inv_type.map(inv => {
return (
<option key={inv.inv_type_cd} value={inv.inv_type_cd}>
{inv.inv_type_name}
</option>
);
})}
</select>
</div>
)
}
}
export default Inv;
看起来您没有在子组件的render函数中返回任何内容。 尝试:
render() {
return (
<div>
<select
value={this.props.invId}
name={this.props.invKey}
onChange={this.handleInvChange.bind(this)}
>
<option className="blank">Select inv name:</option>
{this.state.invData &&
this.state.invData.map(inv => {
return (
<option key={inv.userId} value={inv.userId}>
{inv.invName}
</option>
);
})}
</select>
<select
value={this.props.invType}
name={this.props.invKey}
onChange={this.handleInvTypeChange.bind(this)}
>
<option className="blank">Select inv type:</option>
{this.state.kddData &&
this.state.kddData.kdd_inv_type.map(inv => {
return (
<option key={inv.inv_type_cd} value={inv.inv_type_cd}>
{inv.inv_type_name}
</option>
);
})}
</select>
</div>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.