从小孩修改父组件状态

从小孩修改父组件状态

问题描述:

我对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和这个绑定之间的区别)。

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

我不知道如果我试图做一些事情,这只是不可能的,不可取的,或者如果它只是一个简单的错误。我在这里查了很多问题和官方教程,但他们只是使用传递给函数的参数setState而不是尝试访问状态(在我的情况下计算id)。我也研究了各种教程,因为我相信这是基本概念,但还没有找到解决方案。

谢谢你的帮助。

最佳,

中号

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

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

一个错误是关于不绑定你的addItem和.bind(this)。

您应该将其绑定到您传递的方法。他们可能会在dom或其他组件中调用,所以这种情况会发生变化。但是,如果在传递过程中绑定这个,则上下文将是组件。您的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

感谢您的快速和全面的答复。这帮助我理解了两件事:1)我想要做的是有意而不是反模式,2)我不明白绑定是如何工作的。如果任何人都能指出详细解释这一点的资源,我会非常感激。大多数教程似乎忽略了对此的深入解释。再次感谢 – mgp