Проблема с заполнением ввода и проблема связи с редукцией в React - PullRequest
0 голосов
/ 24 апреля 2020

Существует база, содержащая текст из входных данных:

let data={
  textInput:"",
  inputInfo:{size:""},
};
export const loginReducer=(state=data,action)=>{
    switch (action.type) {
        case "ChangeInputInfoSize":
          if (Number(action.size)|| action.size==="" ){
            let Statecopy={...state};
            Statecopy.inputInfo.size=action.size;
            return {...Statecopy};
          }else {
            return state
        }
        default:
                return state;
    }
}
export const ChangeInputInfoSizeAC=(size)=>({
    type:"ChangeInputInfoSize",
    size
});

, а также компонент и его контейнер:

import React from "react"
import {connect} from "react-redux";
import {DataFilling} from "./DataFilling";
import {ChangeInputInfoSizeAC} from "../store/loginReducer";
let MapStateToProps=(state)=>{
    return {
        inputInfo:state.loginReducer.inputInfo,
        textInput:state.loginReducer.textInput
    }
};
export const DataFillingContainer=connect(MapStateToProps,{ChangeInputInfoSizeAC})(DataFilling)

Компонент:

import React from "react"
export let DataFilling = (props) => {
    let ChangeInputInfoSizeFunc = (e) => {
        props.ChangeInputInfoSizeAC(e.target.value)
    };
<input placeholder="size" value={props.inputInfo.size} onChange={ChangeInputInfoSizeFunc} />
    }

Когда вы пытаетесь заполнить поле, оно не изменяется, но если вы везде замените inputInfo.size на textInput, то все будет работать. Что нужно изменить в первом варианте, чтобы он работал?

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Я думаю, проблема в редукторе, где создание Statecopy

            let Statecopy={...state};
            Statecopy.inputInfo.size=action.size;

В первой строке let Statecopy={...state} создаст новый объект {textInput, inputInfo}, но во второй строке Statecopy.inputInfo фактически ссылается на старый inputInfo , поэтому он перезаписывает size в старом inputInfo и сохраняет свою ссылку неизменной.

Я рекомендую сделать состояния как можно более плоскими или создать новое состояние.

let Statecopy={...state,inputInfo:{size:action.size}};

В Кроме того, вы можете немного улучшить свой код, выполнив следующие действия:

  1. Наименование случая верблюда Javascript соглашение, поэтому вместо let Statecopy пишите let stateCopy

  2. Соглашение о типе отправки в верхнем регистре разделяется подчеркиванием, поэтому вместо "ChangeInputInfoSize" пишите "CHANGE_INPUT_INFO_SIZE"

  3. При объявлении функции используйте const, потому что вы не не хотите случайно перезаписать функцию, поэтому const ChangeInputInfoSizeFunc = (e) => {... является правильным. Это верно и для export const DataFilling.

  4. Для управляемого компонента, такого как DataFilling, только отправляется окончательное состояние, поэтому событие onChange сохранит значение в локальном состоянии, затем событие onBlur отправляет результат в редуктор.

  5. Ограничьте объявление новых переменных настолько, насколько это возможно, поэтому в редукторе вам не нужны stateCopy,

  6. Сделать начальное состояние редуктора переменной const, перезаписывать его не нужно.

  7. в if (Number(action.size)|| action.size==="" ) первая часть будет числом, а вторая часть будет быть пустой строкой. Из-за непротиворечивости и недопущения будущих ошибок делают оба одинаковых. Также вы можете выполнить эту проверку перед отправкой size на редуктор.

Надеемся, что все эти рекомендации помогут избежать ошибок в будущем

0 голосов
/ 25 апреля 2020

Я должен был сделать глубокое копирование

 case "ChangeInputInfoSize":{
        if (Number(action.size)|| action.size==="" ){
            let copyState = {...state};
            copyState.inputInfo = {...state.inputInfo};
            copyState.inputInfo.size=action.size
            return {...copyState};
        }else {
            return state
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...