为什么`this`关键字在React onClick()方法中引用Window not Component

时间:2016-02-23 10:33:34

标签: meteor reactjs

我认为this关键字始终引用React中的组件,但在toggleStyle下面的this方法中返回窗口对象而不是反应组件对象。有人可以帮助我理解为什么会这样吗?

renderDeviceToggle() {

    var arrowAnimation = {
        rotateX: this.state.expanded ? 180 : 0,
        transformOriginY: [ '42%', '42%' ]
    };

    let toggleState = function () {
        // 'this' is the window
        console.log("in toggleState: this: ", this)
        this.setState({expanded: !this.state.expanded});
    };

    return (
        <div className="device-toggle" onClick={toggleState}>
            <div>{console.log("in return: this is the component: ", this)}</div>
            <div className="device-icon icon huge"></div>
            <VelocityComponent duration={300} animation={arrowAnimation}>
                <div className="icon color-blue flex">
                    <i className="icon-caret-down"></i>Hi
                </div>
            </VelocityComponent>
        </div>
    );
},

render() {
    return (
        <div>
            <div className="panel panel-default">
                <div className="panel-heading">
                    <div className="pull-right text-right">
                        <p><a href="/addOrder" className="pull-right">New order </a></p>
                        <p><a href="#"> View all</a></p>
                    </div>
                    <h4>Top orders</h4>
                </div>
                <div className="panel-body">
                    { this.data.orders ?
                        this.renderOrderTable() :
                        <p>Loading</p> }
                </div>
                <div>
                    {this.renderDeviceToggle()}
                </div>
            </div>
        </div>
    );
}

2 个答案:

答案 0 :(得分:4)

您可以使用箭头函数来获得词法绑定this

let toggleState = () => {
    // 'this' should be the component
    console.log("in toggleState: this: ", this)
    this.setState({expanded: !this.state.expanded});
};

或明确bind上下文:

let toggleState = function () {
    // 'this' should be the component
    console.log("in toggleState: this: ", this)
    this.setState({expanded: !this.state.expanded});
}.bind(this);

关于 this在JS中的工作方式,这里有一个很好的解释https://stackoverflow.com/a/3127440/4879

答案 1 :(得分:3)

发生这种情况的原因是因为React只会将类中的顶级函数绑定到“this”。因此,在这种情况下,renderrenderDeviceToggle都会按预期绑定。但是,在renderDeviceToggle内部,您创建了一个React不知道的新函数toggleState。因此,在创建函数时,此代码在正常的javascript规则下工作。

如另一个答案所述,要解决此问题,您需要使用箭头上下文或将新函数显式绑定到'this'。