0

So, I'm working on understanding of how we can change some button id in array iteams.buttons. I read off docs and also this great post How to update single value inside specific array item in redux . But in my case it does not help, because I have some other error, that I cannot catch.

I make a several tests and what I have:

  1. The action send data to reducer normally, because in FORK_TODO I track it via console.log and it display true (as I wanted).
  2. After rerender first time by case FORK_TODO - it gives me the non-changed array of iteams without any changes for some state.iteams.buttons.id that will change own done prop by the condition of the same id and action.id.
  3. After all next rerenders by case FORK_TODO - it destroys my array of buttons, makes it without any objects, just with array of undefined's .

So, I think that the problem in my construction of FORK_TODO reducer, but I cannot figure out where...

Please, help if someone see my stupid mistake in this case :(

import { combineReducers } from 'redux'
import { ADD_TODO, FORK_TODO, ADDED_BUTTON, TOGGLE_BUTTON, EDIT_TODO, DELETE_TODO, FILTER_TODO_UP, FILTER_TODO_DOWN } from '../Variables/Variables'

const initialState = {
    iteams: {
        todos:[],
        buttons:[]
    }
}

function TodoApp(state, action) {
    if (typeof state === 'undefined') {
        return initialState;
    }

    switch (action.type) {
        case ADD_TODO:
            return Object.assign({}, state, {
                iteams: {
                    todos: [
                        ...state.iteams.todos, 
                        {
                            id: action.id,
                            text: action.text,
                        }
                    ],
                    buttons: [
                        ...state.iteams.buttons, 
                        {
                            id: action.id,
                            text: action.text,
                            done: 'false'
                        }
                    ]
                }
            });
        case FORK_TODO:
        console.log(state.iteams.buttons[0].id === parseInt(action.id)); // return "true"!!
            return {
                iteams: {
                    todos: [
                        ...state.iteams.todos
                    ],
                    buttons: [
                        state.iteams.buttons.map(button => {
                            (button.id === parseInt(action.id)) 
                            ? {...state.iteams.buttons, done: action.text}
                            : state.iteams.buttons
                        })
                    ]
                }
            }
        default: 
            return state;
    }
}



export default TodoApp

UPD: It work now:

    case FORK_TODO:
       return {
            iteams: {
                todos: [
                    ...state.iteams.todos
                ],
                buttons: [
                  ...state.iteams.buttons.map(button => {
                    return (button.id === parseInt(action.id)) ?
                        {...state.iteams.button, done: !button.done} : button
                  })
                ]
            }
        }

But! when we update the done in some button, it rewrite all props of this obj. Why? In off docs this way of changing single value rewrite only this obj value, not the values of all.

Max Wolfen
  • 1,923
  • 6
  • 24
  • 42

1 Answers1

1

Try this:

    case FORK_TODO:
    console.log(state.iteams.buttons[0].id === parseInt(action.id));
    console.log("- action.id -");
    console.log(action.id);
    console.log(" - state.iteams.buttons[0] - ");
    console.log(state.iteams.buttons[0]);
    console.log(" - state.iteams - ");
    console.log(state.iteams);
        const newState = {
            iteams: {
                todos: [
                    ...state.iteams.todos
                ],
                buttons: [
                   ...state.iteams.buttons.map(button => {
                    return (button.id === parseInt(action.id)) ?
                        {...state.iteams.button, done: action.text} : button
                  })
                ]
              }
            }
            console.log(" - newState.iteams.buttons[0] - ");
            console.log(newState.iteams.buttons[0]);
            console.log(" - newState.iteams - ");
            console.log(newState.iteams);
            return newState;
Max Wolfen
  • 1,923
  • 6
  • 24
  • 42
Yossi
  • 5,577
  • 7
  • 41
  • 76
  • Thank you, but it does not gives any changes to the array – Max Wolfen Apr 03 '18 at 11:41
  • Updated the answer. Can you append the console.log output to your question? – Yossi Apr 03 '18 at 11:52
  • Oh, you just forgot about coma after 1th `buttons` obj – Max Wolfen Apr 03 '18 at 12:02
  • The console.log output shows in the old state: buttons[0]: { id: 0, text: "asd", done: "false" } In the new state: buttons[0]: { id: 0, text: "asd", done: "true" } – Yossi Apr 03 '18 at 12:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168121/discussion-between-max-wolfen-and-rahamin). – Max Wolfen Apr 03 '18 at 12:21
  • 1
    Need to go back to my work :) Did my answer/comments help? Can you continue on your own? – Yossi Apr 03 '18 at 12:22
  • Yes, now it work, I update my question. Thank you! But now I have a some strange in the props rerendering. See mu UPD question if you can – Max Wolfen Apr 03 '18 at 12:22
  • 1
    Sorry, I need to go back to my work... I suggest that you try to solve it, and if you don't succeed in the next hour or two, post a new question. – Yossi Apr 03 '18 at 12:25