React:无法从子级到父级获取状态

时间:2017-06-19 20:51:13

标签: reactjs

我有一个Login组件:

var React = require('react');
var LoginForm = require('./LoginForm');


    class Login extends React.Component {

        constructor (props) {
            super(props)

            // Bind the this context to the handler function
            this.handler = this.handler.bind(this);

            // Set some state
            this.state = {
                username: '',
                password: '',
                token: ''
            };
        }

        handler(data) {
            this.setState(data);
        }

        render() {
            return (
                <div className="login-container">
                    <div className="outer">
                        <div className="middle">
                            <div className="inner">
                                <LoginForm loginHandler={this.handler}/>
                            </div>
                        </div>
                    </div>
                </div>
            )
        }
    }

    module.exports = Login;

LoginForm一个:

var React = require('react');
import axios from 'axios';

class LoginForm extends React.Component {

    handleLoginClick(event) {
        event.preventDefault();

        var apiBaseUrl = "http://localhost:8000/api-token-auth/";
        var payload={
            "email": "jermaine71@yahoo.com",
            "password": "thePassword"
        };
        axios.post(apiBaseUrl, payload)
            .then(function (response) {
                console.log(response);

                var data = {
                    username: 'jermaine71@yahoo.com',
                    password: 'thePassword',
                }

                this.props.loginHandler(data) . // <-- FAILS HERE. this is undefined

            })
            .catch(function (error) {
                alert('NO');
                console.log(error);
            });
    }

    render() {
        return (
            <form>
                <input type="text" className="form-control" name="username" placeholder="Email Address" required="" />
                <input type="password" className="form-control" name="password" placeholder="Password" required=""/>
                <p></p>
                <button onClick={(event) => this.handleLoginClick(event)} className="btn btn-lg btn-primary btn-block">Login</button>
            </form>
        )
    }
}

module.exports = LoginForm;

我知道实际的axios功能应该在其他地方完成,但我的问题是不同的:我似乎无法获得父级的用户名,密码和令牌信息。该函数在上面显示的位置失败,这是未定义的,并且无法从子级访问处理程序。我在这做错了什么?

3 个答案:

答案 0 :(得分:1)

您必须绑定您的匿名承诺函数

axios.post(apiBaseUrl, payload)
        .then(function (response) {
            console.log(response);

            var data = {
                username: 'jermaine71@yahoo.com',
                password: 'thePassword',
            }

            this.props.loginHandler(data) . // <-- FAILS HERE. this is undefined

        }.bind(this))  // <<<<<<<<<<<<<<<<<<< HERE
        .catch(function (error) {
            alert('NO');
            console.log(error);
        });

答案 1 :(得分:1)

如果使用ES6,则需要在.then函数的handleLoginClick中使用胖箭头功能。

axios.post(apiBaseUrl, payload)
.then( response => {
    var data = {
        username: 'jermaine71@yahoo.com',
        password: 'thePassword',
    };
    this.props.loginHandler(data);
})
.catch( error => {
    alert('NO');
    console.log(error);
});

或者,您可以传入已绑定到this的组件函数:

handleClickResponse(response) {
    var data = {
        username: 'jermaine71@yahoo.com',
        password: 'thePassword',
    };
    this.props.loginHandler(data);
}
handleLoginClick(){
   ...
    axios.post(apiBaseUrl, payload)
    .then(response => this.handleClickResponse(response))
    .catch( error => {
        alert('NO');
        console.log(error);
    });
}

答案 2 :(得分:1)

propsundefined,因为当axios this来电中.then的上下文未引用您期望的this时。

handleLoginClick内执行此操作,您仍然可以访问this

handleLoginClick(event) {
    var here = this

    //... then inside the `then`

    axios.post(apiBaseUrl, payload)
        .then(function (response) {
            //...
            here.props.loginHandler(data)
        })

或者使用胖箭头功能:

.then(response => {
    this.props.loginHandler(data)
})