Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

134
Visualizações
How to set state within a reducer

I have an array of product objects inside my reducer and I have an empty array of brand as well. I want to add all the unique brands from my products object array into my brands array in my reducer, is there any way I can do that?

My Reducer:

import * as actionTypes from './shop-types';

 const INITIAL_STATE = {
 products: [
{
  id: 1,
  brand:"DNMX"
},
{
  id: 2,
  brand: "Aeropostale",
},
{
  id: 3,
  brand: "AJIO",
},
{
  id: 4,
  brand: "Nike",
},
],
  cart: [],
  brands: [], //<---- I want to add all the unique brands inside this array
  currentProduct: null,
};

  const shopReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
  case actionTypes.ADD_TO_CART:
  const product = state.products.find(
    (product) => product.id === action.payload.id
  );
  if (product !== null) {
    return {
      ...state,
      cart: state.cart.concat(product),
    };
  } else {
    return null;
  }
default:
  return state;
 }
 };

export default shopReducer;
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Brands is essentially derived data, meaning it's based off, or reliant on other data. Because of this, you don't actually need to set it in state, and instead rather, just derive it.

I'd normally recommend using Redux Toolkit as it's far simpler, but as you're using old-school Redux, I'd recommend using a library called Reselect. It's a library for creating memoized selectors that you can consume in your component.

For your example, I'd try something like:

// import the createSelector function 
// we'll use to make a selector
import { createSelector } from "reselect"

// create a "getter". this is just a simplified 
// way of accessing state
const selectBrands = (state) => state.products

// create the selector. this particular selector 
// just looks at `products` in state (from your 
// getter), and filters out duplicate values 
// and returns a unique list
const uniqueBrands = createSelector(selectBrands, (items) =>
  items.filter(
    (item, idx, arr) =>
      arr.findIndex((brand) => brand.name === item.name) === idx
  )
)

Then in your component code, you can access this in mapStateToProps:

const mapStateToProps = (state) => ({
  uniqueBrands: uniqueBrands(state),
})

This is currently untested, but should be what you're looking for.

about 4 years ago · Juan Pablo Isaza Relatório

0

It's not really clear if you mean unique brands by cart or products, but it shouldn't change the patterns you'll use to solve this.

First assuming the product list isn't changing, you can simply add them as part of the initial state.

const ALL_PRODUCTS = [
    { id: 1, brand:"DNMX" },
    { id: 2, brand: "Aeropostale" },
    { id: 3, brand: "AJIO" },
    { id: 4, brand: "Nike" }
];

const distinct = (array) => Array.from(new Set((array) => array.map((x) => x.brand)).entries());

const ALL_BRANDS = distinct(ALL_PRODUCTS.map((x) => x.brand));

const INITIAL_STATE = {
    products: ALL_PRODUCTS,
    cart: [],
    brands: ALL_BRANDS, 
    currentProduct: null,
};

If you will have an action that will add a new products and the brands have to reflect that you just apply the above logic during the state updates for the products.

const reducer = (state = INITIAL_STATE, action) => {
    switch(action.type) {
        case (action.type === "ADD_PRODUCT") {
            const products = [...state.products, action.product];

            return {
                ...state,
                products,
                brands: distinct(products.map((x) => x.brand))
            }
        }
    }

    return state;
};

Now for the idiomatic way. You might note that brands can be considered derived from the products collection. Meaning we probably dont even need it in state since we can use something called a selector to create derived values from our state which can greatly simplify our reducer/structure logic.

// we dont need brands in here anymore, we can derive.
const INITIAL_STATE = {
  products: ALL_PRODUCTS,
  cart: [],
  currentProduct: null;
};

const selectAllBrands = (state) => {
  return distinct(state.products.map((x) => x.brand))
};

Now when we add/remove/edit new products we no longer need to update the brand slice. It will be derived from the current state of products. On top of all of that, you can compose selectors just like you can with reducers to get some really complex logic without mucking up your store.

const selectCart = (state) => state.cart; 
const selectAllBrands = (state) => {...see above}  
const selectTopBrandInCart = (state) => {
  const cart = selectCart(state);
  const brands = selectBrands(brands);
  
  // find most popular brand in cart and return it.
};

I would highly recommend you check out reselect to help build composable and performant selectors.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda