Оператор Spread полностью очищает состояние в моем редукторе, когда я переключаю входы - PullRequest
0 голосов
/ 05 марта 2020

все я довольно новичок в React и Redux и застрял с этой проблемой в течение целого дня. Данные отправляются из моего компонента в создатель моих действий, затем в мой редуктор, и состояние обновляется. Однако, когда я изменяю входные данные и начинаю печатать, он очищает все остальные данные в форме, за исключением данных ввода, которые я сейчас набираю. Если я уберу оператор распространения, данные останутся, но из каждого урока я видел, что это не должно произойти. Я что-то не так делаю?

AddProject. js (компонент формы)

import React, { useEffect } from "react";
import styles from "./AddProjects.module.css";
import { connect } from "react-redux";
import {
  validateProjectId,
  validateProjectDescription,
  validateProjectName,
  projectStartDate,
  projectEndDate,
  submitHandler
} from "../../Redux/createProject/action";

const AddProject = props => {
  // useEffect(() => {
  //   console.log("aaa", props);
  // }, [props]);

  return (
    <div className={styles.addProjectContainer}>
      <h5>Create / Edit Project form</h5>
      <hr />
      <form>
        <div>
          <input
            defaultValue=""
            type="text"
            placeholder="Project Name"
            name="projectName"
            style={
              props.form.projectNameError
                ? { backgroundColor: "#F08080", opacity: "0.8" }
                : { backgroundColor: "white" }
            }
            onChange={e => props.validateProjectName(e.target.value)}
          />
        </div>
        <div>
          <input
            type="text"
            placeholder="Unique Project ID"
            name="projectIdentifier"
            value={props.form.projectIdentifier}
            style={
              props.form.projectIdentifierError
                ? { backgroundColor: "#F08080", opacity: "0.8" }
                : { backgroundColor: "white" }
            }
            onChange={e => props.validateProjectId(e.target.value)}
          />
        </div>
        <div>
          <textarea
            placeholder="Project Description"
            name="description"
            value={props.form.description}
            style={
              props.form.descriptionError
                ? { backgroundColor: "#F08080", opacity: "0.8" }
                : { backgroundColor: "white" }
            }
            onChange={e => props.validateProjectDescription(e.target.value)}
          />
        </div>
        <h6>Start Date</h6>
        <div>
          <input
            type="date"
            name="start_date"
            value={props.form.start_date}
            onChange={e => props.projectStartDate(e.target.value)}
          />
        </div>
        <h6>Estimated End Date</h6>
        <div>
          <input
            type="date"
            name="end_date"
            value={props.form.end_date}
            onChange={e => props.projectEndDate(e.target.value)}
          />
        </div>
        <button type="button" onClick={props.submitHandler}>
          <span>Submit</span>
        </button>
      </form>
    </div>
  );
};
//state.form.projectName
const mapStateToProps = state => {
  console.log(state.project);
  return {
    form: state.project
  };
};

const mapDispatchToProps = dispatch => {
  return {
    validateProjectName: payload => dispatch(validateProjectName(payload)),
    validateProjectId: payload => dispatch(validateProjectId(payload)),
    validateProjectDescription: payload =>
      dispatch(validateProjectDescription(payload)),
    projectStartDate: payload => dispatch(projectStartDate(payload)),
    projectEndDate: payload => dispatch(projectEndDate(payload)),
    submitHandler: () => dispatch(submitHandler())
  };
};

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

action. js (создатель действий)

import {
  PROJECT_NAME_CHANGE,
  PROJECT_IDENTIFIER_CHANGE,
  PROJECT_DESCRIPTION_CHANGE,
  START_DATE_CHANGE,
  END_DATE_CHANGE,
  SUBMIT_HANDLER,
  PROJECT_NAME_ERROR,
  PROJECT_IDENTIFIER_ERROR,
  PROJECT_DESCRIPTION_ERROR
} from "./constants";

export const projectNameChange = projectName => {
  return {
    type: PROJECT_NAME_CHANGE,
    projectName
  };
};

export const projectNameError = () => {
  return {
    type: PROJECT_NAME_ERROR
  };
};

export const projectIdChange = projectIdentifier => {
  return {
    type: PROJECT_IDENTIFIER_CHANGE,
    projectIdentifier
  };
};

export const projectIdError = () => {
  return {
    type: PROJECT_IDENTIFIER_ERROR
  };
};

export const projectDescriptionChange = description => {
  return {
    type: PROJECT_DESCRIPTION_CHANGE,
    description
  };
};

export const projectDescriptionError = () => {
  return {
    type: PROJECT_DESCRIPTION_ERROR
  };
};

export const projectStartDate = start_date => {
  return {
    type: START_DATE_CHANGE,
    start_date
  };
};

export const projectEndDate = end_date => {
  return {
    type: END_DATE_CHANGE,
    end_date
  };
};

export const submitHandler = () => {
  return {
    type: SUBMIT_HANDLER
  };
};

export function validateProjectName(payload) {
  return (dispatch, getState) => {
    if (payload.length <= 30) {
      dispatch(projectNameChange(payload));
    } else {
      dispatch(projectNameError());
    }
  };
}

export function validateProjectId(payload) {
  return (dispatch, getState) => {
    if (payload.length < 6) {
      dispatch(projectIdChange(payload));
    } else {
      dispatch(projectIdError());
    }
  };
}

export function validateProjectDescription(payload) {
  return (dispatch, getState) => {
    if (payload.length < 256) {
      dispatch(projectDescriptionChange(payload));
    } else {
      dispatch(projectDescriptionError());
    }
  };
}

// thunk call passed project name
// validateProjectName(name){
//     if(name.length>4 && ){
//         dispatchEvent(setName)
//     }
//     else{
//         dispatch(setNameError)
//     }
// }

index. js (Редуктор)

  PROJECT_NAME_CHANGE,
  PROJECT_IDENTIFIER_CHANGE,
  PROJECT_DESCRIPTION_CHANGE,
  START_DATE_CHANGE,
  END_DATE_CHANGE,
  SUBMIT_HANDLER,
  PROJECT_NAME_ERROR,
  PROJECT_IDENTIFIER_ERROR,
  PROJECT_DESCRIPTION_ERROR
} from "./constants";

const initialState = {
  projectName: "",
  projectIdentifier: "",
  description: "",
  start_date: "",
  end_date: "",
  projectNameError: false,
  projectIdentifierError: false,
  descriptionError: false
};

const createProjectReducer = (state = initialState, action) => {
  switch (action.type) {
    case PROJECT_NAME_CHANGE:
      //   console.log("We changed project name!", state.projectName, action);
      return {
        ...state,
        projectName: action.projectName
      };
    case PROJECT_IDENTIFIER_CHANGE:
      //   console.log("We changed project id!", state, action.projectIdentifier);
      return {
        ...state,
        projectIdentifier: action.projectIdentifier,
        projectIdentifierError: false
      };
    case PROJECT_DESCRIPTION_CHANGE:
      //   console.log("We changed project description", state, action.description);
      return { ...state, description: action.description };
    case START_DATE_CHANGE:
      //   console.log("We changed the start date", state, action.payload);
      return { ...state, start_date: action.payload };
    case END_DATE_CHANGE:
      //   console.log("We changed the end date", state, action.payload);
      return { ...state, end_date: action.payload };
    case PROJECT_NAME_ERROR:
      //   console.log("There was an error with the project name!", state);
      return { ...state, projectNameError: true };
    case PROJECT_IDENTIFIER_ERROR:
      //   console.log("There was an error with the project Id!", state);
      return { projectIdentifierError: true };
    case PROJECT_DESCRIPTION_ERROR:
      //   console.log("There was an error with the project description!", state);
      return { ...state, descriptionError: true };
    case SUBMIT_HANDLER:
      console.log("We submitted yayy", state);
      return initialState;
    //const formData = state;
    //console.log(formData);
    default:
      return state;
  }
};

export default createProjectReducer;

константы. js

export const PROJECT_IDENTIFIER_CHANGE = "PROJECT_IDENTIFIER_CHANGE";
export const PROJECT_DESCRIPTION_CHANGE = "PROJECT_DESCRIPTION_CHANGE";
export const START_DATE_CHANGE = "START_DATE_CHANGE";
export const END_DATE_CHANGE = "END_DATE_CHANGE";
export const SUBMIT_HANDLER = "SUBMIT_HANDLER";
export const PROJECT_NAME_ERROR = "PROJECT_NAME_ERROR";
export const PROJECT_IDENTIFIER_ERROR = "PROJECT_IDENTIFIER_ERROR";
export const PROJECT_DESCRIPTION_ERROR = "PROJECT_DESCRIPTION_ERROR";

rootReducer. js


const rootReducer = (state = {}, action) => {
  return {
    project: createProjectReducer(state.createProject, action)
  };
};

export default rootReducer;

index. js (store создатель)

import ReactDOM from "react-dom";

import { createStore, compose, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunkMiddleware from "redux-thunk";

import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import rootReducer from "./Redux/rootReducer";

const composeEnhancers =
  (typeof window !== "undefined" &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
  compose;

const store = createStore(
  rootReducer,
  composeEnhancers(applyMiddleware(thunkMiddleware))
);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
serviceWorker.unregister();

Ответы [ 3 ]

0 голосов
/ 05 марта 2020

В редукторном редукторе вы всегда должны возвращать всю новую версию состояния, а не только обновленный параметр

Пример

return Object.assign({},prevState,{field: action.value});

(Мы не видим ваш редуктор в вашем сообщении но я думаю, что это проблема)

Хорошая документация здесь - https://redux.js.org/basics/reducers/

0 голосов
/ 05 марта 2020

Ошибка в создании вашего магазина

project: createProjectReducer(state.createProject, action)

должно быть

project: createProjectReducer(state.project, action)

Состояние потеряно из-за того, что оно не было передано субредуктору

0 голосов
/ 05 марта 2020

Использование избыточности для управления состоянием компонента - очень плохая практика. Вместо этого вы должны использовать useState для сохранения состояния каждого из ваших входов и управления ими с помощью onChange Redux следует использовать ТОЛЬКО для переменных, которые связаны с пользовательским интерфейсом и которые должны передаваться между несколькими компонентами вокруг веб-сайт.

https://reactjs.org/docs/hooks-state.html для получения дополнительной информации

Вы должны знать, что каждый раз, когда вы обновляете свой магазин, вы сначала копируете (полностью), а затем новый значения добавляются, а затем текущий магазин заменяется новым. Что приводит к большим проблемам с производительностью и утечке памяти.

...