Home > Software engineering >  How to make a React Hooks who update data between pages
How to make a React Hooks who update data between pages

Time:03-02

I'm trying to create a custom hooks in order to store Cart data.

The cart object:

{ uid: quantity, uid2: quantity2, ...}

The Hook I did:

import { useState } from "react";

// Return a new object without empty values
const clean = (obj) =>
  Object.keys(obj).reduce((acc, key) => {
    if (obj[key]) {
      acc[key] = obj[key];
    }
    return acc;
  }, {});

export const useCart = () => {
  // Cart is [uid]=quantity
  const [cart, setCart] = useState({});

  const updateCart = ({ uid = 0, quantity = 1 }) => {
    const newCart = clean({
      ...cart,
      [uid]: quantity > 0 ? quantity : null
    });

    setCart(newCart);
    console.log(" New Cart : ", JSON.stringify(newCart));
  };

  // Do are they reactive ? Or do we need to useState them
  const count = Object.values(cart).reduce((acc, value) => acc   value, 0);

  // Return all
  return { cart, updateCart, setCart, count };
};

The issue I have

The cart works fine for a single Item but when I update the DOM and re-ask for cart data, they're it's back to initial value.

I'm pretty sure it's because the updateCart() is initialized with initial value who isn't updated... but I don't know how to do it ?

I also tried to use directly setCart() on components instead of updateCart() but nothing better.

I did an example to test it without my project: https://codesandbox.io/s/reverent-tess-8pymji

Thanks.

CodePudding user response:

The problem is that every time the route changes, it will reinitialise your React hook and that will also reinitialise the state on that hook.

You probably are looking to create your custom hook as a Singleton so that it could share the state across multiple components on different routes.

react-singleton-hook is a really neat library that you can use in order to do just that.

You'll have to update the implementation of your hook a bit:

import { useState } from "react";
import { singletonHook } from "react-singleton-hook";

// Return a new object without empty keys
const clean = (obj) =>
  Object.keys(obj).reduce((acc, key) => {
    if (obj[key]) {
      acc[key] = obj[key];
    }
    return acc;
  }, {});

export const useCartImpl = () => {
  // Cart is [uid]=quantity
  const [cart, setCart] = useState({});
  const updateCart = ({ uid = 0, quantity = 1 }) => {
    const newCart = clean({
      ...cart,
      [uid]: quantity > 0 ? quantity : null
    });

    setCart(newCart);
    console.log(" New Cart : ", JSON.stringify(newCart));
  };

  // Do are they reactive ? Or do we need to useState them
  const count = Object.values(cart).reduce((acc, value) => acc   value, 0);

  // Return all
  return { cart, updateCart, setCart, count };
};

export const useCart = singletonHook({}, useCartImpl);

Here's an Update CodeSandbox for your ref.

  • Related