【问题标题】:Modify parent component state from child从子组件修改父组件状态
【发布时间】:2016-09-22 00:32:32
【问题描述】:

我对 React 很陌生(所以这可能很简单),在一个简单的应用程序上尝试它时,我在尝试从子组件中更改父组件的状态时遇到了困难。

为了使应用程序正常工作,父组件必须保持状态,然后将其传递给其他组件。因此,我创建了一个状态更改函数,并将其传递给孩子。请看下面的代码:

js:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      status: [
        {
          id: 1,
          name: 'Item 1',
          selected: false
        }, {
          id: 2,
          name: 'Item 2',
          selected: false
        }]
    }
  }

  addItem(name) {
    let id = this.props.status.length + 1;
    let newItem = this.props.status;
    newItem.push({id, name, selected: true});
    this.setState({
      status: newItem
    });
  }

  render() {
    return (
        <div><ItemList status={this.state.status} addItem={this.addItem} /></div>
    );
  }
}

class ItemList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      search:'',
    };
  }

  handleAddSubmit(event) {
    event.preventDefault();
    let name = this.refs.newit.value;
    this.props.addItem(name);
    this.refs.newit.value='';
  }

  updateSearch(event) {
    this.setState({search: event.target.value});
  }

  render() {
    let filteredItems = this.props.status.filter((item)=> {
      return item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
    });
    return (
    <div>
        <div>
          <input placeholder="Search" type="text"
          value={this.state.search}
          onChange={this.updateSearch.bind(this)}/>
        </div>
        <div>
          {filteredItems.map((item) => {
            return (<button id={item.id}>{item.name}</button>
            );
          })}
          <form onSubmit={this.handleAddSubmit.bind(this)}>
          <input type="text" placeholder="enter your item" ref="newit"/>
          </form>
        </div>
      </div>
      );
  }
}


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

html:

<div id="app"></div>

我明白代码是怎么错的,addItem 函数无法访问状态,但我不知道如何修复它。我试图将状态从父级传递给子级作为道具,然后作为变量备份到 addItem,但这也不起作用(参见下面的代码)。此外,我玩过 .bind(this) 和 .bind(null) 都没有成功(我不太了解 React auto 和 this 绑定之间的区别)。

  addItem(oldStatus, name) {
    let id = oldStatus.length + 1;
    let newItem = oldStatus;
    newItem.push({id, name, selected: true});
    this.setState({
      status: newItem
    });
  }

我不确定我是在尝试做一些不可能、不可取的事情,还是只是一个简单的错误。我已经检查了这里的许多问题和官方教程,但他们只是使用传递给函数的参数来设置状态,而不是尝试访问状态(在我的情况下计算 id)。我还查看了各种教程,因为我认为这是基本概念,但还没有找到解决方案。

感谢您的帮助。

最好的,

M

编辑:我用代码创建了一个 jsfiddle:https://jsfiddle.net/magp/cw8h2pzk/4/

【问题讨论】:

    标签: reactjs babeljs


    【解决方案1】:

    您可以打开控制台查看错误。

    一个错误是关于没有将您的 addItem 与 .bind(this) 绑定。

    您应该将此绑定到您传递的方法。它们可能会在 dom 或其他组件中调用,因此上下文会发生变化。但是,如果在传递时绑定 this,则 this 的上下文将是组件。您的 this.state... 语句将按预期工作。

    另一个错误是每个孩子都应该有一个唯一的键。

    这意味着如果您正在映射一个数组或简而言之迭代数据并返回 jsx,您返回的每个 jsx 都应该有一个唯一的键。

    这是工作的 jsfiddle。我更改的字段如下。

    <form onSubmit={this.handleAddSubmit.bind(this)}>
    
    {filteredItems.map((item) => {
       return (<button id={item.id} key={item.id}>{item.name}</button );
    })}
    

    https://jsfiddle.net/8v2cu95x/1/

    【讨论】:

    • 感谢您快速而全面的回答。这帮助我理解了两件事:1)我想要做的是有意而不是反模式,2)我不明白绑定是如何工作的。如果有人能指出详细解释这一点的资源,我将不胜感激。大多数教程似乎都跳过了对此的深入解释。再次感谢
    猜你喜欢
    • 2019-04-04
    • 2015-04-15
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2016-12-26
    • 1970-01-01
    相关资源
    最近更新 更多