Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

201
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!