Reputation: 3204
First off, I'm new to ReactJS. I've done a lot of searching, but I can't find an answer to this question. Maybe it's simple...
I'm needing to communicate between independent components in ReactJS. Imagine my app does not have control over a 'parent' component in the web page it is called on and the app has something like:
class Widget1 extends React.Component {
render(){
return <button>Update Widget 2</button>
}
}
class Widget2 extends React.Component {
render(){
return <textarea></textarea>
}
}
ReactDOM.render(<Wiget1 />, document.getElementById('widget1'));
ReactDOM.render(<Widget2 />, document.getElementById('widget2'));
And the HTML looks like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Setup</title>
</head>
<body>
...SOME OTHER HTML
<div id="widget1"></div>
...SOME OTHER HTML
<div id="widget2"></div>
...SOME OTHER HTML
</body>
</html>
Is it possible to have these components talk to each other when there is no shared parent?
For instance just passing a value from the button in Widget 1 to the Widget 2 textarea. Obviously that's not at all what I'm doing in the end, but it's in that direction.
Thanks.
Upvotes: 1
Views: 115
Reputation: 441
Sure, your components should communicate somehow.
Parent -> Child
communicaton is done with props. Child behaves according to propeties given from parent.
Child -> Parent
communication is done with(surprize!) properties.
For example:
//Parent's render method
return (
<div>
<Child someEventHandler={(e)=>{console.log('Some event happened!')}}
</div>);
// ...
// Child render method
return (
<div>
<button onClick={(e)=>{if(typeof this.props.someEventHandler === 'function'){this.props.someEventHandler()}}}>
I trigger some event!
</button>
</div>
);
Your child component knows how handle some event(Click, DoubleClick, etc...) and trigger some handler taken from parent with props
. This concept allows us reuse low-level(aka dumb) components. For example, you can implement something like <SearchField onSubmit={...} onReset={...} />
component and render it in different places of your application, but pass different onReset
and onSubmit
callbacks.
Also, your components can communicate with refs. For example:
// Parent's render method
return (
<div>
<Child1 onSomeEvent={(e)=>{this.refs.child2.someMethod(e)}}
<Child2 ref="child2"/>
</div>
);
When you do something like <Child2 ref="child2"/>
In some parent component, reference to instance of Child2
is put into Parent.refs.child2
and you can directly call "public" methods of Child1
.
React is awesome! Good luck!
Sinclerely,
Alexey
Upvotes: 0
Reputation: 5133
If data can flow from <Widget1/>
to <Widget2/>
, then they are not completely independent and can be children of one <ParentComponent/>
.
However, if you still wish to communicate while keeping these <Widget/>
s independent, this can be achieved very easily following the Flux Architecture.
Your widgets can listen to a common Store. When you click on a <button/>
in <Widget1/>
, it would fire an ACTION which would update value of a variable in Store. Both the widgets (<Widget1/>
and <Widget2/>
) would be listening to the change in the same store Store and would update themselves once the Store updates.
//Widget
class Widget extends React.Component{
componentWillMount(){
Store.addChangeListener(this.handleStoresChanged);
}
componentWillUnmount(){ //removeChangeListener }
handleStoresChanged(){
let newCount = Store.getNewCount();
this.setState({ count: newCount });
}
addCount(){
dispatch('ADD_2', {});
}
render(){
return(
<div>
<button onclick={this.addCount.bind(this)}>Add 2 to count</button>
{this.state.count}
</div>
)
}
}
// Widget1 and Widget2 would have the same structure and can extend the above class
Store would then listen to ADD_2
action and then add 2 to a variable called _count
inside store. The getNewCount()
function inside this store will return the value of _count
variable. Since both the widgets are listening to the same store, an action of clicking the button on any widget would change the store and this change will be reflected in both the widgets.
Upvotes: 3