When working with React, you’ll often encounter situations where you need to transform or derive values based on other state or props. This concept is known as derived state, and it's one of the most powerful tools in your React toolkit—if used correctly.
“Derived State: State that can be computed from existing piece of state or prop is called derived state.”
So, let’s dive into it and have a bit of fun while we’re at it.
Let’s start with a typical "oops, I didn’t think this through" example. Imagine we have a list of products, and we want to filter them based on what the user types into a search input. In an ideal world, our search should update dynamically and be super snappy. But, let’s take a quick look at the bad practice approach first.
Here’s how we shouldn’t be handling things:
import React, { useState } from 'react'; const ProductList = () => { const [searchQuery, setSearchQuery] = useState(''); const [products, setProducts] = useState([ { id: 1, name: 'Laptop' }, { id: 2, name: 'Smartphone' }, { id: 3, name: 'Headphones' }, { id: 4, name: 'Smartwatch' }, ]); const [filteredProducts, setFilteredProducts] = useState(products); const handleSearch = (e) => { const query = e.target.value; setSearchQuery(query); setFilteredProducts( products.filter(product => product.name.toLowerCase().includes(query.toLowerCase()) ) ); }; return ( <div> <input type="text" value={searchQuery} onChange={handleSearch} placeholder="Search for a product" /> <ul> {filteredProducts.map((product) => ( <li key={product.id}>{product.name}</li> ))} </ul> </div> ); }; export default ProductList;
Why is this bad practice?
It looks like it works, right? The search input is hooked up, and it filters the products as expected.
But here’s the problem: we’re storing the filtered products as a separate state. This causes unnecessary duplication of data. We already have products in state, and we’re storing the result of the filter operation in another state, which leads to potential bugs, increased memory usage, and makes it harder to keep everything in sync.
Basically, we’re making things more complicated than they need to be.
Now, let's apply a bit of React wisdom and fix the above code using derived state.
This time, instead of keeping two separate state variables (products and filteredProducts), we'll derive the filtered products directly from the products array based on the searchQuery. This way, we avoid redundancy and keep our state clean.
Here’s the improved version:
import React, { useState } from 'react'; const ProductList = () => { const [searchQuery, setSearchQuery] = useState(''); const products = [ { id: 1, name: 'Laptop' }, { id: 2, name: 'Smartphone' }, { id: 3, name: 'Headphones' }, { id: 4, name: 'Smartwatch' }, ]; // Derived state: filter products based on the search query const filteredProducts = products.filter(product => product.name.toLowerCase().includes(searchQuery.toLowerCase()) ); const handleSearch = (e) => { setSearchQuery(e.target.value); }; return ( <div> <input type="text" value={searchQuery} onChange={handleSearch} placeholder="Search for a product" /> <ul> {filteredProducts.map((product) => ( <li key={product.id}>{product.name}</li> ))} </ul> </div> ); }; export default ProductList;
What’s the improvement?
This approach takes advantage of derived state, where the filtered products are computed from existing data, instead of storing an additional copy of the filtered data.
While derived state is often the best choice, it’s not the silver bullet for everything. If your component is dealing with complex calculations or state that’s needed across multiple parts of the application, it might be better to use memoization or store that derived state in a higher-level component or context.
But for simple filtering, sorting, or other lightweight derived values, the example above should be your go-to approach.
To sum up, derived state in React is all about keeping things DRY—don’t repeat yourself. Instead of keeping unnecessary copies of the same data in state, calculate values on the fly based on existing state and props. This leads to cleaner, more efficient code that’s easier to maintain. So, the next time you’re tempted to duplicate data in React, think about whether you can calculate it directly from other sources. Your future self will thank you!
The above is the detailed content of React, we need to talk about Derived States!. For more information, please follow other related articles on the PHP Chinese website!