Bootcamp
Search…
📅
Course Schedule
0: Language and Tooling Teaching Guide
1: Frontend Basics Teaching Guide
2: Backend Basics Teaching Guide
3: Backend Applications Teaching Guide
4: Backend Structure Teaching Guide
5: Full-Stack Applications Teaching Guide
6: Frontend Infrastructure Teaching Guide
7: React Teaching Guide
8: Advanced React Teaching Guide
9: Advanced Topics Teaching Guide
🧮
Algorithms Teaching Guide
💼
Interview Prep Teaching Guide
☺
User Experience Teaching Guide
7.6: Passing Data Between Sibling Components

Introduction

Sometimes we may wish to have 1 component on the page (e.g. an input field) update data in another component on the page (e.g. a text element).
To move data from a component to a sibling component, the simplest way is to pass a function from the parent component as a prop (i.e. "prop function") to its child that wants to update the data. When the child component calls the prop function, that function updates data in the parent (usually stored as state in the parent), which will then trigger an update of the sibling component.

Visualising HTML Element and React Component Hierarchies

In HTML we can represent parent-child relationships between a set of elements in the form of a "tree". For example, the following HTML hierarchy can be represented by the tree diagram below it.
1
<div>
2
<h3>Fruits</h3>
3
<ul>
4
<li><span>dole</span> bananas</li>
5
<li>apples</li>
6
<li>tomatoes</li>
7
</ul>
8
</div>
Copied!
HTML hierarchy represented as a tree.
Similarly, we can also visualise React component hierarchies in tree format. In the following example, theAnnouncement component is the parent of BigText and FinePrint components, and the FinePrint component is the parent of the Tac (terms and conditions) component.
1
function Tac({ terms }) {
2
return <p>{terms}</p>;
3
}
4
​
5
function BigText({ text }) {
6
return <h1 className="hero-text">{text}</h1>;
7
}
8
​
9
// The FinePrint component is the parent of the Tac component in this hierarchy.
10
function FinePrint({ text, tac }) {
11
return (
12
<p className="small">
13
{text}
14
<Tac terms={tac} />
15
</p>
16
);
17
}
18
​
19
// The Announcement component is the parent of BigText and FinePrint components.
20
function Announcement({ bigText, legalDisclaimer, nda, tac }) {
21
return (
22
<div>
23
<BigText text={bigText} />
24
<FinePrint text={disclaimer} tac={tac} />
25
<FinePrint text={nda} tac={tac} />
26
</div>
27
);
28
}
Copied!
The diagram below illustrates the parent-child relationships between components in a tree, and also highlights the props passed between parent-child components and how the props' variable names may differ between parent and child.
React component hierarchy represented as a tree.

Passing Functions as Props

In addition to passing data values as props to child components, we can also pass functions. This enables child components to call functions that rely on variables that only parent components have access to.
In the following example, the Announcement component passes the textClick function to its child component BigText, which enables BigText to call textClick, which logs a variable textClickText that only the Announcement parent component has access to.
1
function Tac({ terms }) {
2
return <p>{terms}</p>;
3
}
4
​
5
// textClick prop is a function passed by parent Announcement component.
6
function BigText({ text, textClick }) {
7
return (
8
<h1 className="hero-text" onClick={textClick}>
9
{text}
10
</h1>
11
);
12
}
13
​
14
function FinePrint({ text, tac }) {
15
return (
16
<p className="small">
17
{text}
18
<Tac terms={tac} />
19
</p>
20
);
21
}
22
​
23
function Announcement({ bigText, legalDisclaimer, nda, tac }) {
24
// Only Announcement has access to the textClickText variable.
25
const textClickText = 'foobar!';
26
​
27
// The textClick function that we pass to BigText can do something with
28
// textClickText, which only Announcement has direct access to.
29
const textClick = () => {
30
console.log(textClickText);
31
};
32
​
33
return (
34
<div>
35
<BigText text={bigText} textClick={textClick} />
36
<FinePrint text={disclaimer} tac={tac} />
37
<FinePrint text={nda} tac={tac} />
38
</div>
39
);
40
}
Copied!
The following is an illustration of how the Announcement parent component passes the textClick function as a prop to BigText and how the data manipulated in textClick belongs to Announcement.
In the next example we will demonstrate how to combine React State, controlled forms, and prop functions to allow a child component to modify data displayed in its sibling.

Passing Data Between Sibling Components Via Prop Functions

The following example assumes a parent component App that has 2 child components: TempForm and Fahrenheit. TempForm renders a controlled form that only allows inputs that are numbers or an empty string. Fahrenheit renders the value of the Celcius temperature stored in App in Fahrenheit.
The logic works as follows.
  1. 1.
    The App component stores a state variable celsiusTemp and its setter function setCelsiusTemp.
  2. 2.
    The App component passes the state setter function setCelsiusTemp as a prop to its child component TempForm, so that TempForm can update celsiusTemp in App when it needs to.
  3. 3.
    The App component also passes the celsiusTemp value to its child component Fahrenheit that renders the Celsius temperature in Fahrenheit. The Fahrenheit component only reads the value of celsiusTemp and cannot modify its value in the parent App component.
  4. 4.
    When the logic in TempForm calls setCelsiusTemp, it triggers a re-render of the App component with the new value of celsiusTemp, which triggers a re-render of the Fahrenheit component with the latest value of celsiusTemp.
  5. 5.
    Meanwhile, TempForm also stores its own local state tempInputValue, which is used to control the value of the input field that TempForm renders to only accept numbers or empty string.
1
// The setCelsiusTemp setter function sets the value of celsiusTemp
2
// in the parent App component.
3
function TempForm({ setCelsiusTemp }) {
4
// TempForm stores its own local state to control the value in its
5
// input field.
6
const [tempInputValue, setTempInputValue] = useState('');
7
​
8
// Update input field value and App component state on valid input.
9
const handleChange = (event) => {
10
const newTempInputValue = event.target.value;
11
// If input is a number or empty string, update the value in the
12
// input field and set the celsiusTemp state in the parent App component.
13
if (newTempInputValue === '' || Number(newTempInputValue)) {
14
setTempInputValue(newTempInputValue);
15
// Convert newTempInputValue from string to number.
16
setCelsiusTemp(Number(newTempInputValue));
17
}
18
};
19
​
20
// Render a controlled input whose value is controlled by handleChange.
21
return <input value={tempInputValue} onChange={handleChange} />;
22
}
23
​
24
// The celciusTemp prop comes from the App component.
25
function Fahrenheit({ celsiusTemp }) {
26
const fahrenheitTemp = (celsiusTemp * 9) / 5 + 32;
27
// Render the app's celsiusTemp value and its corresponding Fahrenheit value.
28
return (
29
<p>
30
{celciusTemp} in Fahrenheit is: {fahrenheitTemp}
31
</p>
32
);
33
}
34
​
35
export default function App() {
36
// celsiusTemp and its setter function setCelsiusTemp must be stored
37
// in the parent App component to pass data between its child components.
38
const [celsiusTemp, setCelsiusTemp] = useState(0);
39
return (
40
<div>
41
<TempForm setCelsiusTemp={setCelsiusTemp} />
42
<Fahrenheit celsiusTemp={celsiusTemp} />
43
</div>
44
);
45
}
Copied!
Last modified 2mo ago