我用对话框和列表编写反应组件。当组件接收“open”prop并尝试在render函数中构建列表时,它会调用ListItem的onClick={ this.handleToggle(item.id) }
函数,因此,这会导致无限循环“render - > onClick - > setState - > render - &gt ; ......“为什么?我怎么能解决这个问题?
handleToggle(value) {
if (this.state.isLoading) {
return;
}
const {checked} = this.state;
const currentIndex = checked.indexOf(value);
const newSelected = checked.slice();
if (currentIndex === -1) {
newSelected.push(value);
} else {
newSelected.splice(currentIndex, 1);
}
this.setState({checked: newSelected});
}
render() {
if (!this.props.show) {
return null;
}
if (this.state.isLoading) {
return(<p>Loading...</p>);
}
const {classes, show, caption} = this.props;
const {checked, projects} = this.state;
return (
<Dialog
open={show}
onClose={this.onCancel}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">{caption}</DialogTitle>
<DialogContent>
<List>
{projects.map(item =>
<ListItem
key={item.id}
role={undefined}
dense
button
onClick={ this.handleToggle(item.id) }
className={classes.listItem}
>
<Checkbox
tabIndex={-1}
disableRipple
checked={checked.indexOf(item.id) !== -1}
/>
<ListItemText primary={item.name}/>
</ListItem>
) }
</List>
</DialogContent>
<DialogActions>
<Button onClick={this.onSuccess} color="primary">OK</Button>
<Button onClick={this.onCancel} color="secondary">Cancel</Button>
</DialogActions>
</Dialog>
);
}
答案 0 :(得分:1)
onClick={ this.handleToggle(item.id) }
将导致每次渲染时评估handleToggle
函数,并且因为在handleToggle中调用setState,它将进入无限循环。 onClick需要一个函数,你应该像
onClick={() => this.handleToggle(item.id) }
这将导致仅在click
事件
答案 1 :(得分:1)
你必须像
一样写onClick={ () => this.handleToggle(item.id) }
因为编写onClick={ this.handleToggle(item.id) }
会立即调用该方法而不是将其作为onClick事件的回调