Неожиданные изменения состояния в функции Redux Reducer - PullRequest
0 голосов
/ 21 февраля 2019

Я только начал изучать Redux с ReactJS.У меня есть простая программа, которая показывает список пользователей и добавляет нового пользователя через форму.

Моя проблема в том, что если я добавлю более 2 пользователей или 3 пользователей, то все пользователи, кроме одного, которого яуказанные в исходном состоянии также обновляются.

Я пробовал и метод Object.assign (), и оператор ES6 Spread, но безрезультатно.

Вот ссылка на CodeSandBox - https://codesandbox.io/s/6290y19j3

1 Ответ

0 голосов
/ 21 февраля 2019

Во-первых, ваш редуктор содержит user ключ в состоянии, и с Object.assign вы не обновляете состояние правильно

Во-вторых, вы сохраняете один экземпляр newUser в своем коде, и если вы обновляетесостояние, подобное

return {
  ...state,
  users: [...state.users, action.newUser]
};

ссылка на объект newUser сохраняется в состоянии, если вы обновляете newUSer для добавления нового пользователя, также изменяется предыдущее значение пользователя.Чтобы решить этот клон объекта и сохранить его в редукторе

Обновлен код редуктора

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

Рабочая демонстрация

...