Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

202
Vistas
Reseting a store object to a default value in SolidJS

How would you completely reset a value in a store in SolidJS

I have something akin to:

interface Item { id: number, price: number, quantity: number } 
​interface State { items: Array<Item> }

export const ItemsContext = createContext()

export const ContextProvider = (props: any) => { 
     const [state, setState] = createStore({items: []})
     
     const incrementItemQuantity = ({id}: Item) => {
         const index = state.items.findIndex(i => i.id === id)

         if(index !== -1) {
             const item = state.items[index] 
             setState("items", index, {quantity: item.quantity + 1})
         }
     }

     const clearItems  = () => {
       setState(produce(s => s.items = []))
     }

     const addItem = (item: Item) => {
       setState(produce(s => s.items.push(item))
     }
    
    const value = [state, { addItem, clearItems, incrementItemQuantity} ]
    return (
     <ItemsContext.Provider value={value} >
      { props.children }
     <ItemsContext.Provider/>
    )
    
}

Adding an item and incrementing its quantity works as expected. When I:

  1. Add an item.
  2. Increment its quantity
  3. Clear the items

I expect the state to be blank. However, If I add an item with the same properties as the first to the list, it is displayed with the old values.

I can't figure out why. What am I not doing right ?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You are not using the store API correctly. For example, the item path gives you the item, you should get the item first, than update it through a setter:

setState("items", index, {quantity: item.quantity + 1});

Here is how you can do it correctly:

// Here path gives us the item
setState("items", index, item => ({...item, quantity: item.quantity + 1}));

// Here path gives us the property
setState('items', index, 'quantity', q => q + 1);

Here is how you can do it. I did not expose store but items. It is up to you.

// @refresh reload
import { createContext, JSX, useContext } from "solid-js";
import { createStore, produce } from 'solid-js/store';
import { render } from "solid-js/web";

interface Item { id: number, price: number, quantity: number }

interface Store {
  items: () => Array<Item>;
  add?: (item: Item) => void;
  increment?: (index: number) => void;
  clear?: () => void;
};

export const CartContext = createContext<Store>();

export const CartProvider = (props: { children: JSX.Element }) => {
  const [store, setStore] = createStore({ items: [{ id: 0, price: 10, quantity: 1 }] })

  const items = () => store.items;
  const add = (item: Item) => setStore('items', items => [...items, item]);
  const increment = (index: number) => setStore('items', index, 'quantity', q => q + 1);
  const clear = () => setStore('items', []);

  return (
    <CartContext.Provider value={{ items, add, increment, clear }}>
      {props.children}
    </CartContext.Provider>
  );
}

const Child = () => {
  const { items, add, increment, clear } = useContext(CartContext);
  return (
    <div>
      <ul>
        {items().map((item, index) => (
          <li>{JSON.stringify(item)} <button onclick={() => increment(index)}>inc</button></li>)
        )}
      </ul>
      <div>
        <button onClick={() => add({ id: items().length, price: 10, quantity: 1 })}>Add Item</button>
        {` `}
        <button onClick={() => clear()}>Clear Items</button>
      </div>
    </div>
  )
};

const App = () => {
  return (
    <CartProvider>
      <Child />
    </CartProvider>
  );
}

render(App, document.querySelector("#app"));
about 4 years ago · Juan Pablo Isaza Denunciar

0

You are not using the store correctly. Check this live example here

import { render } from "solid-js/web";
import { createContext, useContext, For } from "solid-js";
import { createStore } from "solid-js/store";

export const CounterContext = createContext([{ items: [] }, {}]);
export function CounterProvider(props) {
  const [state, setState] = createStore({ items: props.items || []});
  const store = [
    state,
    {
      add: (val) => setState("items", (c) => [...c, val]),
      clear: () => setState("items", () => []),
    },
  ];

  return (
    <CounterContext.Provider value={store}>
      {props.children}
    </CounterContext.Provider>
  );
}

const Counter = () => {
  const [state, { add,clear }] = useContext(CounterContext);
  return <>
    <For each={state.items}>
      {(i) => (<h1>{i}</h1>)}
    </For>
    <button  onClick={() => add(state.items.length + 1)}>Add </button>
    <button  onClick={clear}>Clear </button>
    </>
};

const App = () => (
  <CounterProvider>
    <Counter />
  </CounterProvider>
);
render(() => <App />, document.getElementById("app")!);
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda