在 React 中,父组件如何根据子组件中执行的异步获取函数的响应来设置状态?

In React, how can a parent component set state from the response an async fetch function performed in a child component?

在我的 React 应用程序中,我有一个子组件 LoginForm 如下:

export class LoginForm extends React.Component {
    constructor(props) {
        super(props);
        this.login = this.login.bind(this);
    }

    async login() {
        let data = new FormData();
        data.append('User[email]', document.getElementById('app-login-form-email').value);
        data.append('User[password]', document.getElementById('app-login-form-password').value);
        let loginHandler = this.props.loginHandler;
        const req = await fetch('/site/login', {
            method: 'POST',
            body: data
        });
        const respJson = await req.json();
        loginHandler(respJson);
    }

    render() {
        return(
            <div id="app-login-form">
                <input type="text" id="app-login-form-email" value="test@app.com"></input>
                <br/>
                <input type="password" id="app-login-form-password" value="admin"></input>
                <br/>
                <button onClick={this.login}>Login</button>
            </div>
        );
    }
}

它有一个 prop loginHandler,这是一个从父组件传下来的函数,完整的见这里:

export class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            user: {
                isAuthenticated: props.isAuthenticated || false
            }
        }
        this.bodyHandlers = {
            handleUserLogin: this.handleUserLogin,
        };
        this.handleUserLogin = this.handleUserLogin.bind(this);
    }

    bodyHandlers;
    headerHandlers;
    footerHandlers;

    handleUserLogin(responseJson) {
        this.setState({
            user: {
                isAuthenticated: true,
                data: responseJson.user,
                jwt: responseJson.token
            }
        });
    }

    render() {
        return(
            <Router>
                <Header user={this.state.user} handlers={this.headerHandlers}/>
                <Body user={this.state.user} handlers={this.bodyHandlers}/>
                <Footer user={this.state.user} handlers={this.footerHandlers}/>
            </Router>
        );
    }
}

const domContainer = document.querySelector('#main');
ReactDOM.render(React.createElement(App), domContainer);

然而,每当我尝试这样做时,我都会在控制台中收到以下错误: Uncaught (in promise) TypeError: Cannot read property 'setState' of undefined

我有一个基本的理解,即在承诺的范围内工作时,this 变得很难处理。我尝试了许多不同的排列,包括将函数 that 的局部变量设置为 this。我也试过 fetch .then 语法,这没什么区别。

我是否必须在父组件中将获取代码实现为一个函数并将其作为 prop 传递给子组件调用,还是我遗漏了什么?

谢谢。

我认为问题在于您在绑定之前将方法作为值分配给 bodyHandlers 对象。尝试切换顺序:

constructor(props) {
    super(props);
    this.state = {
        user: {
            isAuthenticated: props.isAuthenticated || false
        }
    }

    this.handleUserLogin = this.handleUserLogin.bind(this);
    this.bodyHandlers = {
        handleUserLogin: this.handleUserLogin,
    };
}