Back to: ReactJS Tutorials
Derived Computed State in React:
In this article, I am going to discuss the Derived Computed State in React with Examples. Please read our previous article where we discussed Lifting State Up in React.
Derived Computed State in React:
At this point in the ‘React State and Events’ module, you already learned quite a bit about state, events, and a lot about React in general. Now, before we end this module, we want to dive into another state-related, very important concept. That’s the concept of derived or computed state, or derived or computed values as you can also say. Let’s explore this concept. Let’s show a little text in a paragraph below the “expenses filter” and above the “expense item” elements in the Expenses.js file,
We want to show “Data for years 2019, 2021, and 2022 is hidden,”. So, basically, we want to list all the years which are currently not selected. Now, this is actually a feature that we’ll remove soon because we don’t need it here in this app, but it is a feature that allows us to explore the important concept of derived values. One way of implementing this here is to register a new state, which we can name “filterInfoText” with a “setFilterInfoText” state updating function. And the initial value can be the “2019, 2021 & 2022” string here.
and then we dynamically output filterInfoText as,
Now, we can update filterChangeHanlder whenever the filter changes. Now, we can check “if (selectedYear == ‘2019’”, we call setFilterInfoText (‘2019, 2021 & 2022’). Else if (selectedYear == ‘2020’”, we call setFilterInfoText (‘2019, 2021 & 2022’) and so on. We can also add the condition for 2021 where we call setFilterInfoText (‘2019, 2020 & 2022’). And “else” for the last case, we will exclude 2022, setFilterInfoText (‘2019, 2020 & 2021’).
That’s how we can implement this. If we save this and check the result,
So, we have that text here. It’s a bit hard to read because it’s not styled as we’ll delete it soon anyways. But you can see that currently 2020 is executed because that’s the year we selected. If we switch this to 2019,
The text is updated and now 2019 is excluded from the text and all the other years are mentioned. Please keep in mind that the filter doesn’t work yet which is why we see all these years. But, the text updates as expected. Nonetheless, this is typically not how you should implement this. Whilst it works,
We are managing an additional piece of state which in the end is redundant. Because this state here is in the end based on another state (useState(‘2020’)). The year we exclude in the above-mentioned state is the year we’re managing in other states. So we’re managing two pieces of state here, even though they both depend on the same source. One state will be enough here. Instead of being managed as a standalone state which updates whenever the other state updates, we should manage the info text as a computed value. And that’s what the derived state or computed state concept is all about. If you are setting a state, that in the end, is directly related to another state, you typically don’t have to manage a separate state. Instead, we have to add a new variable n your component function. And that can be named “filterInfotext” which initially is “2019, 2021 & 2022” text with the year 2020 excluded. And then we can extract these “if else” conditions outside of the handler function, and put them directly in the Expenses component function.
So in the ‘if-else’ conditions, we have to check for filteredYear instead of selectedYear. we use [filteredYear, setFilteredYear] state in our “if” condition, and we simply set our variable to those different pieces of text, instead of updating a separate state. We just dynamically compute the value of filterInfoText variable, and the value will be different depending on which state was selected.
the condition ‘filteredYear == 2020’ is redundant here, since the value for this check is our default value i.e. 2020. So, we can get rid of this check.
So, now, we have this leaner computed code here, which works because when the state is updated when the setFilteredYear function is called, the component function, Expenses will execute again. So, the above code will be executed again, and will derive a new value for “filterInfoText”. Hence, now if we save everything,
we get exactly the same behavior as before. If we switch our filter, the value will be updated.
Even though the value itself is not managed as a state, it’s part of the component that’s re-executed when the state changes. And it depends on the state that changes. So ‘filterInfoText’ is a computed value, a value that we derive based on that state.
And whilst you can also manage multiple states and it wouldn’t be a huge problem using derived values like this, it’s typically the more elegant and recommended approach.
So, we’ll remove the code from our project that we discussed in this article because we don’t need that info text. We just use that to explain the concept of derived state or derived values. Below is the code of the files that are used in this article.
ExpensesFilter.js:
import React from 'react'; import './ExpensesFilter.css'; const ExpensesFilter = (props) => { const dropdownChangeHandler = (event) => { props.onChangeFilter(event.target.value); }; return ( <div className='expenses-filter'> <div className='expenses-filter__control'> <label>Filter by year</label> <select value={props.selected} onChange={dropdownChangeHandler}> <option value='2022'>2022</option> <option value='2021'>2021</option> <option value='2020'>2020</option> <option value='2019'>2019</option> </select> </div> </div> ); }; export default ExpensesFilter;
ExpensesFilter.css:
.expenses-filter { color: white; padding: 0 1rem; } .expenses-filter__control { display: flex; width: 100%; align-items: center; justify-content: space-between; margin: 1rem 0; } .expenses-filter label { font-weight: bold; margin-bottom: 0.5rem; } .expenses-filter select { font: inherit; padding: 0.5rem 3rem; font-weight: bold; border-radius: 6px; }
Expenses.js:
import React, { useState } from 'react'; import ExpenseItem from "./ExpenseItem"; import "./Expenses.css"; import Card from "../UI/Card"; import ExpensesFilter from './ExpensesFilter'; const Expenses = (props) => { const [filteredYear, setFilteredYear] = useState('2020'); let filterInfoText = '2019, 2021 & 2022'; if(filteredYear === '2019'){ filterInfoText = '2020, 2021 & 2022'; } else if(filteredYear === '2021'){ filterInfoText = '2019, 2020 & 2022'; } else { filterInfoText = '2019, 2020 & 2021'; } const filterChangeHandler = selectedYear => { setFilteredYear(selectedYear); }; return ( <Card className="expenses"> <ExpensesFilter selected={filteredYear} onChangeFilter={filterChangeHandler} /> <p>Data for years {filterInfoText} is hidden.</p> <ExpenseItem title={props.items[0].title} amount={props.items[0].amount} date={props.items[0].date} /> <ExpenseItem title={props.items[1].title} amount={props.items[1].amount} date={props.items[1].date} /> <ExpenseItem title={props.items[2].title} amount={props.items[2].amount} date={props.items[2].date} /> </Card> ); } export default Expenses;
In the next article, I am going to discuss Controlled vs Uncontrolled Components and Stateless vs Stateful Components in React with Examples. Here, in this article, I try to explain the Derived Computed State in React with Examples. I hope you enjoy this Derived Computed State in React article.