React:TodoList示例中的子通信

时间:2015-08-14 16:40:27

标签: reactjs

我正在学习React并修改其中一个教程。它是Todo列表,我已经遇到了障碍。我正在尝试添加删除列表项的功能。所以我添加了一个" x"到每个TodoList的末尾。但是孩子如何修改父母state.items?什么是" React"解决这个问题的方法?

var TodoList = React.createClass({
  render: function() {
    var createItem = function(itemText, index) {

    return <li key={index + itemText}>{itemText} <a onClick={function() { // modify the parent item variable somehow?; }}>x</a></li>

    };
    return <ul>{this.props.items.map(createItem)}</ul>;
  }
});
var TodoApp = React.createClass({
  getInitialState: function() {
    return {items: [], text: ''};
  },
  onChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var nextItems = this.state.items.concat([this.state.text]);
    var nextText = '';
    this.setState({items: nextItems, text: nextText});
  },
  render: function() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.onChange} value={this.state.text} />
          <button>{'Add #' + (this.state.items.length + 1)}</button>
        </form>
      </div>
    );
  }
});

React.render(<TodoApp />, mountNode);

2 个答案:

答案 0 :(得分:1)

如果要从其子项修改父项的状态,则需要在父组件中创建一个以您希望的方式修改状态的函数,然后将其作为prop传递给子项。然后,孩子可以只调用this.props.functionName(args),它将触发您在父母身上创建的功能。

要按照列表示例,假设我们有一个如下所示的List组件:

var List = React.createClass({
    getInitialState : function () {
        return ({items : []});
    },
    removeItem : function (num) {
        var items = this.state.items;
        items.splice(num, 1);
        this.setState({items : items});
    },
    addItem : function () {
        var value = React.findDOMNode(this.refs.itemName).value;
        var items = this.state.items;
        items.push(value);
        this.setState({items : items});
    },
    render: function() {
        var items = this.state.items.map(function(item, i) {
            return <Item name={item} key={i} num={i} remove={this.removeItem} />
        }.bind(this));
        return (
            <div>
                List:<br/>
                {items}
                <br/>
                <input type='text' ref='itemName'/>
                <button onClick={this.addItem}>Add Item</button>
            </div>
        );
    }
});

...和一个看起来像这样的Item组件:

var Item = React.createClass({
    render : function () {
        return (
            <div>
                {this.props.name}&nbsp;
                <button onClick={this.props.remove.bind(null, this.props.num)}>Remove</button>
            </div>
        );
    }
});

所有这些List都保留了Items并提供了一个用户可以添加和删除Items的界面。添加一个Item很简单,我们只需要一个按钮,当点击它时,取一个<input>的值并将其添加到List的状态。 React将看到状态转换并为我们重新呈现List,它将显示新的Item。

与将一个Item添加到列表末尾不同,remove函数需要更具体地说明需要删除哪个Item。出于这个原因,我们需要在每个Item上有一个按钮,当单击它时,将通过调用this.props.remove并将其num prop绑定到参数来从列表中删除该项。这将导致列表上的removeItem函数触发,这将从我们的状态中删除该项目。同样,React将看到状态转换,并为我们重新呈现我们的List,省略了删除的项目。

以下是该代码的实际应用:https://jsfiddle.net/rxnpr9sq/

希望有所帮助!如果您有任何其他问题,请与我们联系。

答案 1 :(得分:0)

我认为这就是您所需要的:https://facebook.github.io/react/tips/expose-component-functions.html

Michael Parker花时间用这种方式编写你的具体实现。