如何在Redux Selector中实现可选产品列表的计算逻辑?
You can use Redux's reselect library to create a memoized selector that handles this filtering logic. This will ensure the filtered list updates automatically whenever either the available products or chosen products change, without needing the component to re-mount.
Step 1: Install Reselect (if not already installed)
If you haven't added it to your project yet, install it via npm or yarn:
npm install reselect # or yarn add reselect
Step 2: Create Memoized Selector
Import createSelector from reselect, then define your base selectors and combine them into a selector that does the filtering:
import { createSelector } from 'reselect'; // Base selectors (cleaned up with default empty arrays to avoid errors) const selectAvailableProducts = state => state.products.allProducts || []; const selectChosenProducts = state => state.newproducts.allProducts || []; // Memoized selector to get filtered products export const selectProductsToChooseFrom = createSelector( [selectAvailableProducts, selectChosenProducts], (availableProducts, chosenProducts) => { // Create a set of chosen product IDs for fast lookup const chosenProductIds = new Set(chosenProducts.map(product => product.id)); // Filter available products to exclude those already chosen return availableProducts.filter(product => !chosenProductIds.has(product.id)); } );
Step 3: Use the Selector in Your Component
In your component, use this selector with useSelector (if using React-Redux hooks):
import { useSelector } from 'react-redux'; import { selectProductsToChooseFrom } from './path/to/your/selectors'; function YourDropdownComponent() { const productsToChooseFrom = useSelector(selectProductsToChooseFrom); return ( <select> {productsToChooseFrom.map(product => ( <option key={product.id} value={product.id}> {product.name} </option> ))} </select> ); }
Key Improvements & Explanations:
- Memoization:
createSelectorcaches the filtered result. It only recalculates whenavailableProductsorchosenProductschange, so your component will re-render with the updated list immediately when either state slice updates—no more waiting for re-mounts. - Object Reference Fix: Your original logic used
includes(el)which checks for object reference equality. If API-fetched products are new objects (even with identical data), this won’t work. Using aSetof IDs is more reliable and efficient for lookups. - Safety Checks: Adding
|| []to base selectors prevents errors if the state slices areundefinedwhen the component first mounts.
This approach keeps your filtering logic centralized in Redux and ensures your dropdown stays in sync with the state automatically.
内容的提问来源于stack exchange,提问作者tachko

