我已经阅读了这篇文章:React setState not Updating Immediately
并意识到setState是异步的,可能需要第二个arg作为函数来处理新状态。
现在我有一个复选框
class CheckBox extends Component {
constructor() {
super();
this.state = {
isChecked: false,
checkedList: []
};
this.handleChecked = this.handleChecked.bind(this);
}
handleChecked () {
this.setState({isChecked: !this.state.isChecked}, this.props.handler(this.props.txt));
}
render () {
return (
<div>
<input type="checkbox" onChange={this.handleChecked} />
{` ${this.props.txt}`}
</div>
)
}
}
并且正被另一个应用程序使用
class AppList extends Component {
constructor() {
super();
this.state = {
checked: [],
apps: []
};
this.handleChecked = this.handleChecked.bind(this);
this.handleDeleteKey = this.handleDeleteKey.bind(this);
}
handleChecked(client_id) {
if (!this.state.checked.includes(client_id)) {
let new_apps = this.state.apps;
if (new_apps.includes(client_id)) {
new_apps = new_apps.filter(m => {
return (m !== client_id);
});
} else {
new_apps.push(client_id);
}
console.log('new apps', new_apps);
this.setState({apps: new_apps});
// this.setState({checked: [...checked_key, client_id]});
console.log(this.state);
}
}
render () {
const apps = this.props.apps.map((app) =>
<CheckBox key={app.client_id} txt={app.client_id} handler={this.handleChecked}/>
);
return (
<div>
<h4>Client Key List:</h4>
{this.props.apps.length > 0 ? <ul>{apps}</ul> : <p>No Key</p>}
</div>
);
}
}
因此,每次复选框状态更改时,我都会更新this.state.apps
中的AppList
当我console.log new_apps
时,一切都可以正常工作,但是console.log(this.state)
显示状态没有立即更新,这是可以预期的。我需要知道的是,当我需要执行进一步的操作(例如注册所有这些选定的字符串或其他内容)时,如何确保状态被更新
答案 0 :(得分:3)
setState使您可以在设置状态后创建回调函数,以便获得真实状态
this.setState({stateYouWant}, () => console.log(this.state.stateYouWant))
在您的情况下:
this.setState({apps: new_apps}, () => console.log(this.state))
答案 1 :(得分:2)
其他人对setState回调有正确的答案,但我也建议将CheckBox设置为无状态,并从MyApp传递isChecked作为道具。这样,您只需保留一项是否已检查项目的记录,而无需在两者之间进行同步。
答案 2 :(得分:2)
实际上,不应有两个州保持同一事物。取而代之的是,复选框应为无状态,状态应仅保留在AppList中,然后向下传递:
const CheckBox = ({ text, checked, onChange }) =>
(<span><input type="checkbox" checked={checked} onChange={() => onChange(text)} />{text}</span>);
class AppList extends React.Component {
constructor() {
super();
this.state = {
apps: [
{name: "One", checked: false },
{ name: "Two", checked: false }
],
};
}
onChange(app) {
this.setState(
previous => ({
apps: previous.apps.map(({ name, checked }) => ({ name, checked: checked !== (name === app) })),
}),
() => console.log(this.state)
);
}
render() {
return <div>
{this.state.apps.map(({ name, checked }) => (<CheckBox text={name} checked={checked} onChange={this.onChange.bind(this)} />))}
</div>;
}
}
ReactDOM.render(<AppList />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>