1

I found lot's of solutions online, but I've done my best for a week and found no way to solve it. I believe the fault to be the reducer ADD_GOAL, that is why i left it empty.

Thanks alot! :)

I want to add objects to the goals array. I always want to initialize goals empty, but I want to be able to add and remove objects freely. The idea is to save the objects like this.

{ list: { '0': { id: 0, dueDate: 'By May 28th I Will have: ', goals: [ {0: {...} 1: {...} 3: {...} } ] } '1':{ id: 0, dueDate: 'By June 31st I Will have: ', goals: [ {2: {...} 4: {...} } } 

Reducer

export default (state = {}, action) => { let copyList = [{ description: '213', aim: 12, progress: 2, percentage: 20 }]; switch (action.type) { case 'ADD_DUEDATE': return { ...state, [action.payload.id]: action.payload } case 'ADD_GOAL': return { } case 'DELETE_TODO': return state.filter((item, index) => index !== action.payload) default: return state; } } 

Component

import React from 'react'; import { connect } from 'react-redux'; class List extends React.Component { state = { id: 0, goalId: 0 } createDueDate = () => { this.props.add({ id: this.state.id, dueDate: "By May 28th I Will do something: ", goals: [{}] }) this.setState({ id: this.state.id + 1 }); } addGoal = () => { this.props.addToList({ goals: [{ id: this.state.goalId, description: '213', aim: 12, progress: 2, percentage: 20 }] }) this.setState({ goalId: this.state.goalId + 1 }) } render() { return ( <div> <div> <button className="btn btn-secondary" onClick={this.createDueDate}></button> </div> <div> <button className="btn btn-primary" onClick={this.addGoal}></button> </div> </div> ); } } function mapStateToProps(state) { return { list: state.list } } function mapDispatchToProps(dispatch) { return { add: (value) => { dispatch({ type: 'ADD_DUEDATE', payload: value }) }, get: (id) => { dispatch({ type: 'GET_DUEDATE', payload: id }) }, addToList: (value) => { dispatch({ type: 'ADD_GOAL', payload: value }) } } } export default connect(mapStateToProps, mapDispatchToProps)(List); 
2
  • What are you trying to achieve? Trigger a re-render when a new goal is added and update the UI? Commented May 22, 2019 at 19:13
  • I am trying to add objects to the goals array by clicking a button. Commented May 22, 2019 at 19:30

1 Answer 1

4

Let's assume a nested array of items in our reducer:

const initialState = { items : { deepItem :[1, 2, 2], reallyDeepItem: { a : [1,2,3] b : {'a', 'c'} } } } 

And now let's assume 2 actions, one to add an item on state.items.deepItem that we're gonna call ADD_DEEP_ITEM and another one to insert an item on state.items.reallyDeepItem.a called ADD_DEEPER_ITEM. Let's write our reducer:

const Reducer = (state = initialState, action) =>{ switch(action.type){ case 'ADD_DEEP_ITEM': return { ...state, items : { ...state.items, deepItem : state.items.deepItem.concat(action.data) } } case 'ADD_DEEPER_ITEM': return{ ...state, items :{ ...state.items, reallyDeepItem:{ ...state.items.reallyDeepItem, a : state.itens.reallyDeepItem.a.concat(action.data) } } } } } 

That's it, properly updated! Just remember to always spread all properties and then override the ones you want.

Sign up to request clarification or add additional context in comments.

1 Comment

in case of "'ADD_DEEP_ITEM'" even we are using spread operator .reference of a and b will still point to old state reference as they are objects and not primitive type. by using spread operator reference of "reallyDeepItem" will be copied only . let me now my undestanding is correct or not ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.