Redux Reducer功能中的意外状态更改

时间:2019-02-21 12:00:59

标签: reactjs redux react-redux

我刚刚开始使用ReactJS学习Redux。我有一个简单的程序,它显示用户列表并通过表单添加新用户。

我的问题是,如果我添加了2个或3个以上的用户,那么除我在初始状态中指定的用户外,所有其他用户也将得到更新。

我也尝试了Object.assign()方法和ES6 Spread运算符,但都无济于事。

这是CodeSandBox的链接- https://codesandbox.io/s/6290y19j3

1 个答案:

答案 0 :(得分:1)

首先,您的reducer包含处于状态的user键,并且使用Object.assign不能正确更新状态

其次,您在代码中维护newUser的单个实例,并且如果您像这样更新状态,则

return {
  ...state,
  users: [...state.users, action.newUser]
};
如果更新newUSer以添加新用户,则

newUser对象引用将存储在状态中,以前的用户值也会更改。要解决此克隆对象并保存在reducer中

更新的Reducer代码

// 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"
  }
};

但是,更好的方法是使值处于组件中的状态并使用它,而不是在类外声明变量

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);

Working demo