1

I've been struggling with this for awhile now and I just cant seem to get it working correctly. I'm currently building a project for work that allows franchise owners to change their hours of operations online and I came across the following problem while trying to store state.

Here is the state that I need to upload:

const [storeHours, setStoreHours] = useState<WeeklyRanges>({
    monday: [{ from: '09:00', to: '10:00' }],
    tuesday: [{ from: '09:00', to: '10:00' }],
    wednesday: [{ from: '09:00', to: '10:00' }],
    thursday: [{ from: '09:00', to: '10:00' }],
    friday: [{ from: '09:00', to: '10:00' }],
    saturday: [{ from: '09:00', to: '30:00' }],
    sunday: [{ from: '09:00', to: '14:00' }]
  }); 

And here is the currently solution I am working on:


 const handleChange = (
    e: React.ChangeEvent<{ name: string; checked?: unknown; value?: unknown }>
  ) => {
    const [section, key] = e.target.name.split('.');

    return setStoreHours(
      { ...storeHours, [section]: { ...storeHours[section], [key]: e.target.value } }
    );
  };

This is giving me weird issues such as the following that I cant figure out my way around.

enter image description here

enter image description here

Thanks so much for taking a look!

MKaplan
  • 31
  • 4

1 Answers1

0

Since your state is a an Object which has a value as array . es6 spread syntax is not enough to create a new copy of the array . es6 spread syntax is useful only when your values in the objects are primitive.

const myObj = { name: "user1", age: "20" };

You need to deep clone an object whose values are another array or object . You can use lodash cloneDeep method . cloneDeep.

Assuming your name is the combination of something like monday.from .

    const handleChange = (
  e: React.ChangeEvent<{ name: string; checked?: unknown; value?: unknown }>
) => {
  const [section, key] = e.target.name.split('.');
  const newStoredHours = cloneDeep(storedHours);
  // you can mutate this as its a brand new object
  newStoredHours[section][0][key] = e.target.value;

  return setStoreHours(
    newStoredHours
  );
};

Different Deep clone techniques

Shyam
  • 5,292
  • 1
  • 10
  • 20
  • cloneDeep function from lodash sometime create problem, it bind the reference to the cloned object, so I rather prefer `cloneObj = JSON.parse(JSON.stringify(object))` – Rhythm sharma May 22 '21 at 16:05
  • JSON.parse(JSON.stringify(object)) will clone the object but you will have data loss if the value of your object is undefined. Please refer this - https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript – Shyam May 22 '21 at 16:07
  • 1
    Yes agree @shyam, but my solution was more specific to the problem, here in the `storeHours` object we are not using any function or undefined values inside the object so I think we can use `JSON.stringify` – Rhythm sharma May 22 '21 at 17:01
  • I ended up using JSON.parse option as lodash was giving me a lot of issues with typescript but thanks so much for your help! – MKaplan May 22 '21 at 17:18