ReactJS组件似乎没有隔离范围

时间:2016-05-19 15:34:37

标签: javascript reactjs components

我是来自AngularJS的ReactJS新手。我希望有一个带有按钮的组件,当您单击该按钮时,它会显示一个textarea。在React中给出了这个自定义组件:

Toggle = React.createClass({
    UI: {
        showNotes: false
    },
    toggleShowNotes: function () {
        this.UI.showNotes = !this.UI.showNotes;
        console.log(this.UI.showNotes);
        this.setState({UI: this.UI});
    },
    render: function () {
        return (
            <div className="well">
                <div className="form-group">
                    <button className="btn btn-default" onClick={this.toggleShowNotes}>+ Add Notes</button>
                </div>
                {this.UI.showNotes ? <textarea className="form-control" placeholder="Notes"></textarea> : null }
            </div>
        )
    }
});

请注意,只要单击按钮,我就会将组件UI.showNotes的状态记录到控制台。如果我将几个这些组件放在我的主应用程序中,如下所示:

var App = React.createClass({
  render: function () {
    return (
      <div>
        <Toggle></Toggle>
        <Toggle></Toggle>
        <Toggle></Toggle>
        <Toggle></Toggle>
        <Toggle></Toggle>
      </div>
    );
   }
});

ReactDOM.render(
        <App/>,
        document.getElementById('container')
    );

单击button时,登录到控制台的内容始终与之前登录到控制台的值相反。 问题是无论我点击哪个<Toggle>按钮都是如此。换句话说,好像只有一个this.UI个实例而不是每个实例一个零件。这让我很困惑,given ReactJS' documentation on the matter

  

React负责为每个类组件创建一个实例,因此您可以使用方法和本地状态以面向对象的方式编写组件,但除此之外,实例在React的编程模型中并不是非常重要并且是可以管理的通过React本身。

我希望this.UI对每个组件都是唯一的,而不是&#34;全球&#34;在组件的所有实例之间共享的对象。

  1. 为什么不是这样?
  2. 由于情况并非如此,为了达到预期的效果,对我进行重构的最佳方法是什么?

1 个答案:

答案 0 :(得分:4)

使用

UI: {
    showNotes: false
},

您实际上创建了一个在所有实例之间共享的对象,因为它在原型上定义,因此如果您更改showNotes,则所有实例都会看到更改 它与React无关,但与JavaScript无关。

而是使用这样的东西:

Toggle = React.createClass({
    getInitialState: function() {
        return {showNotes: true};
    },
    toggleShowNotes: function () {
        this.setState({showNotes: !this.state.showNotes});
    },
    render: function () {
        return (
            <div className="well">
                <div className="form-group">
                    <button className="btn btn-default" onClick={this.toggleShowNotes}>+ Add Notes</button>
                </div>
                {this.state.showNotes ? <textarea className="form-control" placeholder="Notes"></textarea> : null }
            </div>
        )
    }
});