React(Facebook):受控复选框的托管状态

Mat*_*ira 32 javascript facebook reactjs

我在尝试使用React创建一个复选框来选择和取消选择其他单独的复选框(选择/取消选择全部)时遇到了一些问题.我已经阅读了http://facebook.github.io/react/docs/forms.html,发现受控非受控 <input> s 之间存在差异.我的测试代码如下:

var Test = React.createClass({
    getInitialState: function() {
        return {
            data: [
                { id: 1, selected: false },
                { id: 2, selected: false },
                { id: 3, selected: false },
                { id: 4, selected: false }
            ]
        };
    },
    render: function() {
        var checks = this.state.data.map(function(d) {
            return (
                <div>
                    <input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} />
                    {d.id}
                    <br />
                </div>
            );
        });
        return (
            <form>
                <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector
                <br />
                {checks}
            </form>
        );
    },
    __changeSelection: function(e) {
        var id = e.target.getAttribute('data-id');
        var state = this.state.data.map(function(d) {
            return {
                id: d.id,
                selected: (d.id === id ? !d.selected : d.selected)
            };
        });

        this.setState({ data: state });

    },
    __changeAllChecks: function(e) {
        var value = this.refs.globalSelector.getDOMNode().checked;
        var state = this.state.data.map(function(d) {
            return { id: d.id, selected: value };
        });

        this.setState({ data: state });
    }
});

React.renderComponent(<Test />, document.getElementById('content'));
Run Code Online (Sandbox Code Playgroud)

"全局选择器"按预期工作:选中后,将选中所有其他检查.问题是,__changeSelection()当单击其他复选框之一时,不会触发处理程序.

我不知道做这项工作的正确方法是什么.也许React模型不是模拟这种交互的最佳模型?我能做什么?

提前致谢

Mic*_*oix 43

在你的render功能,范围thischecks映射功能是不同的render,这是你需要的范围__changeSelection,所以this.__changeSelection不会找到一个__changeSelection属性.如果您添加.bind(this)到映射函数的最后,你可以绑定它的范围相同thisrender:

var checks = this.state.data.map(function(d) {
    return (
        <div>
            <input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} />
            {d.id}
            <br />
        </div>
    );
}.bind(this));
Run Code Online (Sandbox Code Playgroud)

在旁注中,我只是将其传递id给处理函数而不是分配数据属性.这将消除在处理程序中找到该元素的需要:

var checks = this.state.data.map(function(d) {
    return (
        <div>
            <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
            {d.id}
            <br />
        </div>
    );
}.bind(this));
Run Code Online (Sandbox Code Playgroud)

然后更新您的__changeSelection函数以传入id第一个arg并删除属性查找行:

__changeSelection: function(id) {
    var state = this.state.data.map(function(d) {
        return {
            id: d.id,
            selected: (d.id === id ? !d.selected : d.selected)
        };
    });

    this.setState({ data: state });

}
Run Code Online (Sandbox Code Playgroud)

以下是一个将它们放在一起的示例,以及一个jsfiddle供您试用:

/** @jsx React.DOM */

var Test = React.createClass({
    getInitialState: function() {
        return {
            data: [
                { id: 1, selected: false },
                { id: 2, selected: false },
                { id: 3, selected: false },
                { id: 4, selected: false }
            ]
        };
    },
    render: function() {
        var checks = this.state.data.map(function(d) {
            return (
                <div>
                    <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
                    {d.id}
                    <br />
                </div>
            );
        }.bind(this));
        return (
            <form>
                <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector
                <br />
                {checks}
            </form>
        );
    },
    __changeSelection: function(id) {
        var state = this.state.data.map(function(d) {
            return {
                id: d.id,
                selected: (d.id === id ? !d.selected : d.selected)
            };
        });

        this.setState({ data: state });

    },
    __changeAllChecks: function() {
        var value = this.refs.globalSelector.getDOMNode().checked;
        var state = this.state.data.map(function(d) {
            return { id: d.id, selected: value };
        });

        this.setState({ data: state });
    }
});

React.renderComponent(<Test />, document.getElementById('content'));
Run Code Online (Sandbox Code Playgroud)

  • @ matheus-emm使用`this .__ changeSelection(id)`会立即调用该函数(例如渲染时).我们只想传递函数的引用,以便稍后可以通过`onChange`事件调用它.例如,如果您在浏览器控制台中键入`console.log`,它将打印出该函数,但如果您键入`console.log()`,它将触发实际函数.`anyFunc.bind(this,arg)`将创建一个绑定到`this`的新函数,并将任何传入的参数添加到原始函数中,但不会调用它. (7认同)