【发布时间】:2018-08-10 11:08:45
【问题描述】:
我有一个包含子组件的组件。子组件有许多复选框。每个复选框的 onClick 将复选框的状态变为 true 并更新整个组件。每次点击checkbox 时,我都需要父组件中选中复选框的标签,因此我将一个函数从父组件传递给子组件。在componentDidUpdate() 中,当我调用从父级通过道具传递的函数时,它工作得非常好。目前,我得到了子组件的更新状态,即选中复选框的标签,我可以通过 console.log 看到它们。但是,如果我不使用console.log(),而是使用setState({SelectedLabels:selected}),它会进入无限循环并在片刻之后显示错误:超出最大限制。我搜索了很多。 React 文档说你不能在componentDidUpdate()、componentWillUpdate 甚至shouldComponentUpdate() 中调用setState()。有人可以告诉我在哪里可以使用它吗?
这是我的代码:
父组件:
class BuildingsModal extends React.Component {
state = {
open: false,
breadcrumbEntries: [{ title: "World" }],
disabled: true
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
// This is my function that goes to child to get run after child gets updated so the received array can be used to set the disabled state of this component. If I do not call setState of this component and only console.log() function, it work fine. There is an issue with the state update. Please help!!
handleSelectedItems = selectedArray => {
selectedArray.length > 0 && this.setState({disabled:false});
console.log(
"SelectedArray:",
selectedArray,
"disabled",
this.state.disabled
);
};
render() {
const { fullScreen } = this.props;
const { open, breadcrumbEntries, disabled } = this.state;
return (
<div>
<PageHeader
title="Dashboard"
subtitle="33 Irving Place, New York, NY 10003"
icon
onClick={this.handleClickOpen}
/>
<Dialog
open={open}
onClose={this.handleClose}
scroll="body"
fullScreen={fullScreen}
maxWidth="sm"
PaperProps={{
style: {
paddingLeft: 77.5,
paddingRight: 77.5,
paddingTop: 20,
paddingBottom: 44,
borderRadius: 23
}
}}
>
<DialogHeader>
<Title>33 Irving Place</Title>
<DialogActions>
<LinkButton onClick={this.handleClose} type="danger">
Cancel
</LinkButton>
<LinkButton onClick={this.handleClose} type="success">
Save
</LinkButton>
<LinkButton onClick={this.handleNext} disabled={disabled}>
Next
</LinkButton>
</DialogActions>
</DialogHeader>
<ContentWrapper>
<Breadcrumb
entries={breadcrumbEntries}
getIndex={index => console.log("index is: ", index)}
/>
<Content type="world" getSelectedItems={this.handleSelectedItems} />
</ContentWrapper>
</Dialog>
</div>
);
}
}
export default BuildingsModal;
子组件:
class Contents extends React.Component {
constructor(props) {
super(props);
this.state = {
data: null,
checkedItems: new Map(),
filteredItems: []
};
this.handleChange = this.handleChange.bind(this);
}
componentDidUpdate() {
var filteredItems = [];
const filterItems = (value, key, map) => {
value === true && filteredItems.push(key);
};
this.state.checkedItems.forEach(filterItems);
this.props.getSelectedItems(filteredItems);
}
getWorldData() {
this.setState({
data: [
"United State",
"United Kingdom",
"China",
"Korea",
"Japan",
"Pakistan",
"India",
"Bangladesh"
]
});
}
getCountryData() {
this.setState({
data: [
"New York",
"Los Angeles",
"Chicago",
"Houston",
"Phoenix",
"Philadilphia",
"Dallas",
"Reno"
]
});
}
getBuildingData() {
this.setState({
data: [
"33 Irving Place",
"22 Irving Place",
"11 Irving Place",
"3344 Irving Place",
"44 Irving Place",
"77 Irving Place",
"55 Irving Place",
"66 Irving Place"
]
});
}
componentDidMount() {
const { type } = this.props;
type === "world"
? this.getWorldData()
: type === "country"
? this.getCountryData()
: type === "building"
? this.getBuildingData()
: alert("No Data to show");
}
handleChange(e) {
const label = e.target.value;
const isChecked = e.target.checked;
this.setState(prevState => ({
checkedItems: prevState.checkedItems.set(label, isChecked)
}));
}
render() {
const {
data,
checkedItems
} = this.state;
return (
<Content type={data === null ? "progress" : null}>
{data === null ? (
<ActivityIndicator size={100} />
) : (
<FlexColumn>
{data.map(item => (
<Label
control={
<Checkbox
checked={checkedItems.get(item)}
value={item}
color="default"
onChange={this.handleChange}
/>
}
label={item}
key={item}
/>
))}
</FlexColumn>
)}
</Content>
);
}
}
export default Contents;
可能你们中的一些人建议我为什么需要在 componentDidUpdate() 中而不是在 handleChange(e) 中调用来自 prop 的函数。 回答:当我设置子组件的状态时,它不会立即更新,所以我无法调用该函数,通过道具传递,更新状态。我需要通过这个函数发送更新的状态。请大家帮帮我!
【问题讨论】:
-
reactjs 中有一种模式。 Lifting State Up。它会解决很多问题。
-
感谢@Gobinda,值得了解和帮助解决我的问题!
-
非常欢迎。乐于助人。
标签: reactjs