Reputation: 65
I just started learning Redux with ReactJS. I have a simple program which shows the list of users and adds a new user through a form.
My problem is that if I add more than 2 users or 3 users, then all the users except for the one I specified in the initial state are getting updated as well.
I have tried both Object.assign() method and ES6 Spread operator as well to no avail.
Here is a link to the CodeSandBox - https://codesandbox.io/s/6290y19j3
Upvotes: 1
Views: 1006
Reputation: 281686
Firstly, your reducer contains user
key in state and with Object.assign
you are not updating the state correctly
Secondly, you maintain a single instance of newUser
in you code and if you update the state like
return {
...state,
users: [...state.users, action.newUser]
};
newUser object reference is stored in state if you update newUSer to add new user the pervious user value is also changed. To solve this clone the object and save in reducer
Updated Reducer code
// Reducer Function which adds the new user to the old state.
const myReducer = (state = initState, action) => {
if (action.type == "ADD_USER") {
console.log(action);
console.log(" ");
console.log(state);
return {
...state,
users: [...state.users, {...action.newUser}]
};
} else {
return state; // Default case when no action of relevant type is fired, returning the Initial State which contains the name "Sriram"
}
};
However a better way is to have the values in state in the component and use it instead of declraing a variable outside of class
import React from "react";
import "./styles.css";
import { connect } from "react-redux";
class App extends React.Component {
// Function to handle the form fields and update the newUser object accordingly.
state = {
id: null,
name: "",
age: null
};
addId = e => {
this.setState({ id: parseInt(e.target.value, 10) });
};
addName = e => {
this.setState({ name: e.target.value });
};
addAge = e => {
this.setState({ age: parseInt(e.target.value, 10) });
};
// Function that handles the Form Submit.
addUser = e => {
e.preventDefault();
this.props.addUser({
...this.state
});
};
render() {
console.log(this.props.users);
const userList = this.props.users.map(user => {
return (
<div>
<p>
User {user.id} - {user.name} is {user.age} years old{" "}
</p>
</div>
);
});
return (
<div className="App">
<h1>Users Application</h1>
<h3>The list of users is: </h3>
<h3>{userList}</h3>
<form>
<label htmlFor="id">
ID
<input type="text" onChange={this.addId} />
</label>
<label htmlFor="name">
Name
<input type="text" onChange={this.addName} />
</label>
<label htmlFor="age">
Age
<input type="text" onChange={this.addAge} />
</label>
<button onClick={this.addUser}>ADD USER</button>
</form>
</div>
);
}
}
// Function to map the state to the props of the App component.
const mapStateToProps = state => {
return state;
};
// Function to dispatch the action to the store.
const mapDispatchToProps = dispatch => {
return {
addUser: user => {
dispatch({ type: "ADD_USER", user });
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
Upvotes: 1