简体   繁体   中英

Communicating between different components which doesnt have a parent-child relationship in reactjs

Lets say i have 2 different DOM elements

<div id="firstDiv">
</div>
<div id="secondDiv">
</div>

Now lets say i render some html inside the firstDiv using

React.render(firstComponent(null),document.getElementById('firstDiv');

Now lets say i fetch some data from a server inside the firstComponent and then i gotto render part of the data inside secondDiv , whats the best way to do it ??Can i call React.renderComponent(,document.getElementById("secondDiv")) from inside the firstComponent ?? And how to achieve a two-way communication between them ??? Lets say now i click a link in the html rendered in the secondDiv then how to change the text inside the firstDiv ??

If i generalize this question it would be "How do i render html inside multiple DOM elements from one single component and then communicate across these components which are rendered in different DOM elements???"

This can be achieved by regular parent-child communication , except in this case you do not have any parent.

But you can still pass to the root component some functions that will be called inside the 2 components and trigger the rendering

Here is a working demo of the exemple you asked:

var First = React.createClass({
    render: function() {
        return <div>Hello1 {this.props.name}</div>;
    }
});


var Second = React.createClass({
    render: function() {
        return <div onClick={this.props.onSecondClicked}>Hello2 {this.props.name}</div>;
    }
});

function onSecondClicked() {
    React.render(<First name="World updated!" />, document.getElementById("first"));
}

React.render(<First name="World" />, document.getElementById("first"));

React.render(<Second name="World" onSecondClicked={onSecondClicked}/>, document.getElementById("second"));

JsFiddle link


Calling React.render inside the 2nd component should normally work (maybe not during during the render phase but this is not a good idea anyway). However it creates a huge coupling between your 2 components.

You can also create a "root component" that will be a parent of the 2 components.

If you have a lot of components to synchronize, you may use an event bus for cross-component communication.

This comment was too long to fit inside a comment, so that's why i'm pulling it out here.

I think you should take a look at Flux architecture what Facebook uses internally to manage their React apps, and which is now opensourced. Inside Flux, your case would be as follows:

  • when firstComponent is rendered (mounted) you deliver an action to the store ( container for your application/domain state ) to indicate that the store should initially pull the data from the server. When the data is available the Store would emit a ( change ) event, that "hey, I fetched the data successfully, you can come and get it"
  • Both of your component already set up a change listener to the store, so when the store emitted the change event, your components will demand the new data, by calling a getter on the store (eg getState() ). Both of your components would render only that part of the data, what they are interested in.
  • When in secondComponent an action happens (say an onClick) which would alter the state of the application, this action (web API event) would trigger a Flux Action (a plain old JS helper method) which will end in the Store modifying the state. (there's a dispatcher in the chain, among others i'm not talking about now)
    • The store would change it's initial state to the new one, say from Hello World to Hello, World! I'm updated Hello, World! I'm updated .
    • Upon state change, the store emits a change event again, and your first component updates its state accordingly.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM