how trigger event parent to child in Reactjs
That's not how React functions, unfortunately. You are trying to use Menux.handleToggle
as the callback of the onLeftIconButtonTouchTap
prop, right? So when someone clicks the left icon button, you want the Menux
component to execute the handleToggle
function?
That won't work for two reasons:
- When you call
Menux.handleToggle
, you are not calling it on an instance!Menux
is a reference to the class itself. It doesn't have the internal state that you are expecting. Moreover,handleToggle
is an instance method. This means it can only be executed on instances of theMenux
class. - You may be referencing the
Menux
class, but as discussed above, that is not the same instance that React creates when you render the<Menux />
element.
It's really hard to adequately articulate why it's wrong, it's just fundamentally wrong on a few levels hehe. Long story short: you just cannot call the function of a class like that and expect it to change an instance of that class that is not being specified.
Let's move past that. Now, there's a convoluted way of getting your code to work in the way you've written it, but I think it's better to help you understand a more idiomatic way of doing it. That is to say, a more "React way" of getting done what you want.
We want to "Lift the State Up". This concept is this article: https://facebook.github.io/react/docs/lifting-state-up.html
I highly recommend reading that article.
Why do we "lift state up?" Well in React, child nodes don't communicate with each other. Only children and parents communicate with each other. In fact, parents communicate by providing data and functions, children communicate only by calling the functions parents give them.
Imagine you're a kid, one of 5 siblings. You each have a cell phone, but you don't know the phone numbers of your siblings. You only have your parents phone number. But you need to convey some information to some of your siblings. What do you do? You call your parents phone number, relay them the information, and the parents will call your siblings and relay the data to them.
That's how React works.
So how do we apply this to your situation? Instead of the Menu determining itself when it's open, let's have the parent tell the Menu when it's open. This way, the parent can give both the Menux
component and the AppBar
component a function that they can use to say "Hey mom, can you close the menu?"
We will lift the state from the Menux component to the App component.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
openmenu: false
}
}
handleClose = () => this.setState({openmenu: false});
handleToggle = () => this.setState({openmenu: !this.state.openmenu});
render() {
return (
<div>
<AppBar
title="Aqui empezara todo"
onLeftIconButtonTouchTap = {this.handleToggle}
/>
<Menux openmenu={this.state.openmenu} handleToggle={this.handleToggle} handleClose={this.handleClose} />
</div>
);
}
}
Ah ha! Now our App determines when the menu is closed and when it's not. It is the single source of truth! But, it provides AppBar
and Menux
with some functions that they can call if they want to change the state in the parent. So how will Menux
change?
export default class Menux extends React.Component {
render() {
return (
<div>
<RaisedButton
label="Toggle Drawer"
ref="menu"
onTouchTap={this.props.handleToggle}/>
<Drawer width={200} openSecondary={false} open={this.props.openmenu} >
<AppBar title="menu"
onLeftIconButtonTouchTap = {this.props.handleClose}
/>
<MenuItem onTouchTap={this.props.handleClose}>Mi perfil</MenuItem>
<MenuItem onTouchTap={this.props.handleClose}>Mis usuarios</MenuItem>
<MenuItem onTouchTap={this.props.handleClose}>Mis unidades</MenuItem>
</Drawer>
</div>
);
}
It uses the functions that the parent passed it in order to set the state in the parent. A nice, easy, reusable component!
This is the React way of doing things. Parent-child only communication, state and functions passed down to children, children call those functions to change state higher up in the tree. Beautiful!
"But, but, but...I really don't want to do things the React way!"
Fiiiiine. Thankfully, someone else answered (so I don't have to :]) with a very simple way to accomplish what you want to do, without having to restructure your application to ahem a more idiomatic way.
Use a ref
to keep a reference to the child component, so you can call handleToggle
from the parent as you want:
<Menux ref={(menu)=>{this.menu = menu}}/>
Then:
<AppBar
title="Aqui empezara todo"
onLeftIconButtonTouchTap = {this.menu.handleToggle}
/>