Max Wolfen
Max Wolfen

Reputation: 2033

Redux/react. How to change some element in the array of Redux store?

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.

Upvotes: 0

Views: 871

Answers (1)

Yossi
Yossi

Reputation: 6027

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;

Upvotes: 1

Related Questions