【问题标题】:Unable to bind handler in React无法在 React 中绑定处理程序
【发布时间】:2018-06-30 00:50:34
【问题描述】:

我正在尝试将父组件的方法绑定到其子组件的状态,但我无法获得所需的结果。我检查了 App 组件中“this”的值,它仍然指向 App 组件。它不应该指向 ItemsList 组件,因为它是使用 bind() 绑定到它的吗?有人可以指出我正在犯的错误。

import React from 'react';
import {render} from 'react-dom';

class Item extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <div> {this.props.value} </div>;
  }
}

class ItemList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      itemArray: ['Work', 'Learn React']
    }
    this.props.adder.bind(this);
    console.log(this.props.adder)
  }

  render() {
    const items = this.state.itemArray.map(el=><Item key={el} value={el} />);
    return (
      <div> 
        <h2> To Do List </h2>
        <ul>{items}</ul>
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  addElement (data) {
    let items = this.state.ItemList;
    items.push(<Item value={data} />);

  }

  render() {
    return (
      <div>
        <input type="text" ref={input=>this.input=input} />
        <input type="button" value="Add" onClick={()=>this.addElement(this.input.value)}/>
        <ItemList adder={this.addElement} />
      </div>
    );
  }
}


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

【问题讨论】:

    标签: javascript reactjs binding components


    【解决方案1】:

    它不应该指向 ItemsList 组件,因为它是使用 bind() 绑定到它的吗?

    嗯,你的步骤不对。

    App 组件中

    您需要将ItemList(子)组件引用存储在 App(parent) 组件中。

    <ItemList adder={this.addElement} bindChild =  {(ref)=>this.itemList = ref}/>
    

    ItemList组件中

    ItemList 组件挂载时需要调用bindChild 方法。

    componentDidMount(){
      this.props.bindChild(this);
    }
    

    现在,在您的 App(父)组件中,您在 this.itemList 属性中具有 ItemList(子)组件的引用。

    App 组件中,您可以使用this.itemList 来更新ItemList(子)组件的状态。

    addElement(data) {
        let items = this.itemList.state.itemArray;
        console.log(items);
        const newItem = <Item value={data} />
    
        this.itemList.setState({ itemArray : [...items, newItem]})
      }
    

    请查看codesandbox上的完整示例

    【讨论】:

    • 感谢您帮助我。我还想问一件事。理想情况下,我们应该将 'this.props.bindChild(this)' 放在哪里。在“构造函数”或“componentDidMount”中,为什么?
    • 你需要this对象。所以,你可以调用它。构造函数以及
    【解决方案2】:

    虽然您想要的在技术上是可行的,但这是一种更明确且易于理解的方法。

    我重构了你的代码,使数据流只向一个方向流动,从App 到 `Itemimport React from "react"; 从“react-dom”导入{渲染};

    我还将ItemItemList 更改为分别以valueitems 作为道具的无状态组件。

    主要变化是App持有状态,而不是ItemList

    const Item = ({ value }) => <div>{value}</div>;
    
    const ItemList = ({ items }) => (
      <div>
        <h2>To Do List</h2>
        {items.map(item => <Item key={item} value={item} />)}
      </div>
    );
    
    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          items: ["Work", "Learn React"]
        };
      }
      addElement(value) {
        this.setState(state => ({
          items: [...state.items, value]
        }));
      }
      render() {
        return (
          <div>
            <input type="text" ref={input => (this.input = input)} />
            <input
              type="button"
              value="Add"
              onClick={() => this.addElement(this.input.value)}
            />
            <ItemList items={this.state.items} />
          </div>
        );
      }
    }
    
    render(<App />, document.querySelector("#root"));
    

    这是一个包含您的工作应用程序的 CodeSandbox:https://codesandbox.io/s/4r4v0w5o94

    【讨论】:

    • 是的。但是我想这也行不通,因为我们不能改变 props 并且无论哪种方式都无法将此绑定函数向上传播到父级。有没有其他方法可以实现子内部父级的绑定回调?
    • 我已经重构了您的代码并编辑了我的答案。如果您有任何问题,请告诉我
    猜你喜欢
    • 1970-01-01
    • 2016-05-26
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多