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>
}
}
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
Your mistake is that you're passing a function that will return this.handlerMethod
instead of call it:
handlerMethod: ((message) => this.handlerMethod) // this returns the handlerMethod function, doesn't call it
Should be
handlerMethod: ((message) => this.handlerMethod(message))
You can also pass it directly:
handlerMethod: this.handlerMethod
The reason passing it directly works is because you're binding the context of handlerMethod
inside the constructor for LayoutComponent
, meaning this
inside handlerMethod
will be fixed to LayoutComponent
( see Note bellow )
Here's a short example:
Layout Component
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>;
}
}
Page Component
// pass the handlerMethod directly
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={handlerMethod} />
</ div>
);
}
Single Component
export default class SingleComponent extends Component {
// ...
handleButtonClick(event) {
// ...
this.props.handlerMethod("You pressed the button!"); // call the passed method here
// ...
}
// ...
}
Note : Technically, you could override bound this
by calling new this.handlerMethod
but this isn't happening so you're fine.
If you simply want to pass the method down, you do it like this:
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={handlerMethod} />
</ div>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.