Somename Somename - 1 year ago 86
React JSX Question

Target object based on a value of a key of that object which is an element in an array

How do I target what object based on a value of a key of that object which is an element in an array.

Reducer:

const initialState = {
posts: []
}


export default function newData (state = initialState, action) {
switch (action.type) {
case "updateNumber":
return {
...state,

/* How to determine which object's number I should update? */
/* The payload is the id */
number: this.state.number ++ // <== need help here.
}
default:
return state
}
}


Data returned from an API call will be appended to posts:

posts:

[
{
id: '1',
name: 'Name One',
number: 11
},
{
id: '2',
name: 'Name Two',
number: 22
},
{
id: '3',
name: 'Name Three',
number: 33
}

]


In the component I'm rendering it :

class Posts extends Component {

renData () {
console.log("ThePosts: ", this.props.posts);
return posts.map((post, postIndex) => {
return (
<View key = {postIndex}>
<TouchableOpacity
onPress={() => updateNumber(post.id)}
>
<Text> {post.number} </Text>
</TouchableOpacity>
</View>
)
});
}

render(){
return(
<View style={style.container}>
{this.renData}
</View>
)
}

}

function mapDispatchToProps(dispatch) {
return {
updateNumber: (id) => {
dispatch(updateNumber(id))
}
}
}

function mapStateToProps(state) {
return {
posts: state.posts,
}
}

export default connect( mapStateToProps, mapDispatchToProps ) ( Posts );


How to determine which object's
number
is to be updated?

Note: I tried this approach but I'm finding it very difficult to append API call's data to an object. It's easier with arrays.

Please assist.

Answer Source

Assuming that updateNumber is actually just incrementing the number, you must first find the index of the object in the array that you want to update in the reducer using the id. You can then create a new array that replaces the object with an incremented object:

export default function newData (state = initialState, action) {
  switch (action.type) {
    case "updateNumber": {
      const { posts } = state;
      // find object to update
      const index = posts.findIndex(({ id }) => id === action.id);

      if (index > -1 ) {
        // create new object with existing data and increment number
        const updatedData = {...posts[index]};
        updatedData.number++;

        // return new posts array that replaces old object with incremented object at index
        return { posts: [...posts.slice(0, index), updatedData, ...posts.slice(index + 1)]};
      }

      // return state if no object is found
      return state;
    }
    default:
      return state
  }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download