bgmaster bgmaster - 1 month ago 9
Javascript Question

Passing a function down multiple children components in React using ES6

I have a

LayoutComponent
,
PageComponent
, and
SingleComponent
.

When my user clicks a button, I want to display a message to the user on a
NewPageComponent
that my application routes to using Meteor's
FlowRouter
.

To do this, I am storing the message in
LayoutComponent
's state, and then passing this message and a
handlerMethod
down as props to the
SingleComponent
via
PageComponent
, which is a stateless functional component.

I am not having any luck passing the
handlerMethod
down properly to the
SingleComponent
in order to set the message state on
LayoutComponent
.

I know this is a simple syntax issue, but could someone help me find my error?

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>
);
}


Component:

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>
}
}

Answer

You aren't actually calling your handlerMethod in the code you posted. So this:

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

Should be either:

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

Or more simply:

handlerMethod: this.handlerMethod