Still confused about updating state with redux

Hi all.
So I know you’re not supposed to update state directly in redux?
I have these lines from my reducer:

let copyBreak = [...state];
copyBreak = [--defaultBreak,defaultSession];
return copyBreak;

this way i’m making a shallow copy first of state , but it seems wrong and pointless as state still updates.

or should I just do this:

state = [--defaultBreak,defaultSession];
return state;

the code works, but I have a feeling I’m not doing it the correct react/redux way?
basically either defaultBreak or defaultSession are incremented/decrementd by one , depending on the action.

Thanks :slight_smile:

It doesn’t make much sense what you have there as we’re lacking the context.

You are making a copy of the state for no reason afaics. You are returning a new array with two elements, you don’t use any of the values that are currently in the state so there’s no point referencing it.

The reducer is a function that looks like this:

(state: State, action: Action) => State

So it takes a data structure of a specific shape (State) and an action (Action, which is an object with a type field + possibly some other fields) and returns a data structure of the same shape as State.

NOTE I am writing the type of things these are, just treat this as pseudocode, it’s to try to make it clear what is going into the function and what is coming out

As I say there is no context here, but I assume you are doing the pomodoro timer?

If you are returning your state as that array of two items, that’s your state. An array with a time and whatever session is. I don’t think this is what you meant to do as it’s very difficult to deal with (an object is what it should be, like { break: 300, session: "whatever this is" }, but anyway).

When you decrement, you return an array with the break and session, exactly the same types, but in that case the number for the break would be decremented.

const initialState = [defaultBreak, defaultSession];

function timer (state = initialState, action) {
  switch (action.type) {
    case "DECREMENT":
      return [state[0] - 1, state[1]];
    case etc.....

Do you see that it’s just a function that takes what the current values of the state are (ie the things you’re interested in that get changed by user input) then, depending on what message is sent, returns a new version of that state with adjusted values.

1 Like

Never mind, I understand it
found some old tutorial that’s helping :slight_smile:
sorry for the unneeded post.

Just one thing re copying state. You are returning a new array anyway, and as I said I can’t see the context this code is in so following may not apply, but:

JS objects are referenced, so if you mutate an object, the reference is still the same. If you mutate the state instead of returning an entirely new version of it, nothing is going to happen in the app it’s attached to. The libraries used to join redux to React/Vue/etc use shallow comparisons, so they will check if the state has changed before they update anything. If the reference is the same, ipso facto the state hasn’t changed, so nothing will update.

1 Like

Yes, so that’s why I should return a new object instead of changing state?

Yep yep. If you return the same object stuff will break, normally in subtle and weird ways that you don’t notice at first

1 Like

Edit again, I’m not sure if I’m doing this correctly or not?
From what I read what I have so far should be correct? But user stories 12-15 are not passing. I haven’t solved the earlier ones, but I think these should pass at this stage. Plus I’m getting some strange errors after running the test:

Uncaught TypeError: Cannot read property ‘disconnect’ of undefined
at bundle.js:657
Uncaught Error: Script error. (:0)
at a.onerror (bundle.js:593)

Any insight would be great. Thanks! :slight_smile:

Forgot to add the link to my codepen, it’s very crude at this point so ignore that: