简体   繁体   English

reactjs —解决setState异步问题

[英]reactjs — Solving setState async problem

I've read this post: React setState not Updating Immediately 我读了这篇文章: React setState不立即更新

and realized that setState is async and may require a second arg as a function to deal with the new state. 并且意识到setState是异步的,可能需要第二个arg作为函数来处理新状态。

Now I have a checkbox 现在我有一个复选框

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>
            )
    }
}

And is being used by another app 并且正在被另一个应用程序使用

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> 
        );
    }


}

So every time the checkbox status changes, I update the this.state.apps in AppList 因此,每次复选框状态更改时,我都会更新this.state.apps中的AppList

when I console.log new_apps , everything works accordingly, but console.log(this.state) shows that the state is not updated immediately, which is expected. 当我console.log new_apps ,一切都可以正常工作,但是console.log(this.state)显示状态没有立即更新,这是可以预期的。 What I need to know is how I can ensure the state is updated when I need to do further actions (like register all these selected strings or something) 我需要知道的是,当我需要执行其他操作(例如注册所有这些选定的字符串或其他内容)时,如何确保状态得到更新

setState enables you to make a callback function after you set the state so you can get the real state setState使您可以在设置状态后创建回调函数,以便获得真实状态

this.setState({stateYouWant}, () => console.log(this.state.stateYouWant))

in your case: 在您的情况下:

this.setState({apps: new_apps}, () => console.log(this.state))

The others have the right answer regarding the setState callback, but I would also suggest making CheckBox stateless and pass isChecked from MyApp as a prop. 其他人对setState回调有正确的答案,但我也建议将CheckBox设置为无状态,并通过MyApp传递isChecked作为道具。 This way you're only keeping one record of whether the item is checked, and don't need to synchronise between the two. 这样,您只需保留一项是否已检查项目的记录,而无需在两者之间进行同步。

Actually there shouldn't be two states keeping the same thing. 实际上,不应有两个状态保持同一状态。 Instead, the checkbox should be stateless, the state should only be kept at the AppList and then passed down: 相反,复选框应该是无状态的,状态应仅保留在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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM