使用ES6在React中将函数传递给多个子组件

时间:2016-10-20 20:49:48

标签: javascript reactjs meteor ecmascript-6 flow-router

我有LayoutComponentPageComponentSingleComponent

当我的用户点击某个按钮时,我想在NewPageComponent上向用户显示我的应用程序使用Meteor FlowRouter路由到的用户的消息。

为此,我将邮件存储在LayoutComponent的状态,然后通过handlerMethod将此邮件和SingleComponent作为道具传递给PageComponent ,这是一个无国籍的功能组件。

我没有任何好运将handlerMethod正确地传递给SingleComponent,以便在LayoutComponent上设置消息状态。

我知道这是一个简单的语法问题,但有人可以帮我找到我的错误吗?

LayoutComponent:

export default class LayoutComponent extends Component {
  constructor() {
    super();

    this.state = {
      message: null
    };

    this.handlerMethod = this.handlerMethod.bind(this);
  }

  handlerMethod(message) {
    this.setState({ message: message });
  }

  render() {
    // the PageComponent is actually passed via FlowRouter in this.props.content, so it needs to be cloned to add props
    let contentWithProps = React.cloneElement(this.props.content, { message: this.state.message, handlerMethod: ((message) => this.handlerMethod) });
     return (
       <div>{contentWithProps}</div>
     );
  }
}

PageComponent:

const PageComponent = ({ message, handlerMethod }) => {
  return (
    <div>
      <SingleComponent message={message} handlerMethod={(message) => handlerMethod} />
    </ div>
  );
}

组件:

export default class SingleComponent extends Component {
  constructor() {
    super();

    this.state = {
    };
    this.handleButtonClick = this.handleButtonClick.bind(this);
  }

  handleButtonClick(event) {
    event.preventDefault();
    // do some more stuff...
    this.props.handlerMethod("You pressed the button!");
    FlowRouter.go("newPage");
  }

  render() {
    <div>
      <button onClick={this.handleButtonClick}>button</button>
    </div>
  }
}

3 个答案:

答案 0 :(得分:3)

您实际上并未在发布的代码中调用handlerMethod。所以这个:

handlerMethod: ((message) => this.handlerMethod)

应该是:

handlerMethod: ((message) => this.handlerMethod(message))

或更简单:

handlerMethod: this.handlerMethod

答案 1 :(得分:1)

您的错误在于您传递的函数将返回this.handlerMethod而不是调用它:

handlerMethod: ((message) => this.handlerMethod) // this returns the handlerMethod function, doesn't call it

应该是

handlerMethod: ((message) => this.handlerMethod(message))

您也可以直接传递它:

handlerMethod: this.handlerMethod

直接传递它的原因是因为你在handlerMethod的构造函数中绑定了LayoutComponent的上下文,意味着this中的handlerMethod将固定为{ {1}}(请参阅下面的注释

这是一个简短的例子:

布局组件

LayoutComponent

页面组件

export default class LayoutComponent extends Component {
  constructor() {
    // ...
    this.handlerMethod = this.handlerMethod.bind(this); // handler is bound
  }

  handlerMethod(message) {
    // ...
  }

  render() {
    let contentWithProps = React.cloneElement(
      this.props.content, { 
        message: this.state.message, 
        handlerMethod: this.handlerMethod // pass the handler directly
      }
    );

    return <div>{contentWithProps}</div>;
  }
}

单一组件

// pass the handlerMethod directly
const PageComponent = ({ message, handlerMethod }) => {
  return (
    <div>
      <SingleComponent message={message} handlerMethod={handlerMethod} />
    </ div>
  );
}

注意:从技术上讲,您可以通过调用export default class SingleComponent extends Component { // ... handleButtonClick(event) { // ... this.props.handlerMethod("You pressed the button!"); // call the passed method here // ... } // ... } 来覆盖绑定的this,但这不会发生,所以你很好。

答案 2 :(得分:0)

如果您只想传递方法,请按以下方式执行:

const PageComponent = ({ message, handlerMethod }) => {
  return (
    <div>
      <SingleComponent message={message} handlerMethod={handlerMethod} />
    </ div>
  );
}