How to Make Sibling React Components Communicate

Ramvardhan R
4 min readJul 29, 2021

The Problem

Let’s say you have a <Comments /> component. Inside it you have two children <CreateComment /> and <ListComments />. <ListComments /> renders the list of comments passed to it. <CreateComment /> renders an input box. <ListComment /> also renders a reply button next to each comment. When the button is clicked we want to populate our input box in <CreateComment /> with the comment we click on enclosed within double quotes. So basically we need a way to communicate between <ListComments /> and <CreateComment />

You can see the demo of the required behavior in the below codesandbox:

Comments.jsx
CreateComment.jsx
ListComments.jsx

The Solution

There are three ways to do this.

  1. Lifting the Common State to the Common Parent
  2. Using Redux/Context
  3. Using RxJS Subject

Most people are oblivious to the 3rd option and I really prefer the 3rd option in many cases.

Lifting the Common State to the Common Parent

i.e. Lifting the state comment to <Comments />

Remove the useState() line from CreateComment.jsx and add it to Comments and pass the state as props to the CreateComment component.

Now you can use setComment to do the job in handleReply()

The problem with this is that comment is supposed to be a state that is local to <CreateComment />. We placed it in the parent component for the sole reason to mutate it in response to an event in a sibling component.

Using Redux/Context

You can do a similar thing with redux where instead of lifting the state to the common parent, you can store it in redux. From <ListComments /> you can issue an action to mutate it and in <CreateComment /> you can access it as you access any other state in redux.

The problem again with this approach is that comment is supposed to be local to <CreateComment /> but we put it in the global state.

I am not presenting the code for this as this method is extensively covered by many articles out in the internet.

Using RxJS Subject (My Preference)

RxJS subjects allow you to create a stream to which you push events and also subscribe to those events. In our case we’ll create a replyTo$ stream and use it for communication between the siblings.

Send data to <CreateComment /> through the replyTo$ stream

Subscribe to the stream in <CreateComment />

The good thing about this approach is that comment and setComment() remains where they should be and you don't have to go to any other file other than CreateComment.jsx to understand how comment is being mutated.

Conclusion

We saw three ways to make sibling components communicate in React:

Lifting the Common State to the Common Parent

  • Pro: Simple
  • Con: The common state gets placed in an unrelated component

Using Redux/Context

  • Pro: In cases where the children are nested deeply, avoids prop drilling
  • Con: The common state which usually belongs to one component is placed in the global state where many components can potentially access it. For someone new to the codebase, they may not know that only one/two component actually use that state.

Using RxJS Subject

  • Pro: Keeps state where it is supposed to be. Can also be used with Redux/Context where the stream variable is placed in redux/context to avoid prop drilling.
  • Con: Additional Library

Did I miss to think about anything? Let me know in the comments. Thanks!

Originally published at https://perspectives-blog.netlify.app.

--

--