有一个包含输入文本的基:
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,那么一切都会正常工作。第一个选项中需要更改哪些内容才能工作?
我想问题出在创建Statecopy
的减速器中
let Statecopy={...state};
Statecopy.inputInfo.size=action.size;
在第一行let Statecopy={...state}
将创建一个新对象{textInput, inputInfo}
,但在第二行Statecopy.inputInfo
实际引用了旧的inputInfo,因此它覆盖了旧inputInfo
中的size
,并保持其引用不变。
我建议尽可能使状态平坦,或者确保创建新的状态。
let Statecopy={...state,inputInfo:{size:action.size}};
此外,您可以通过以下步骤对代码进行一些改进:
Camel大小写命名是Javascript约定,因此不编写
let Statecopy
而是编写let stateCopy
调度类型约定是用下划线分隔的大写字母,因此不写
"ChangeInputInfoSize"
而写"CHANGE_INPUT_INFO_SIZE"
在声明函数时,请使用
const
,因为您不希望意外覆盖函数,所以const ChangeInputInfoSizeFunc = (e) => {...
是正确的。export const DataFilling
也是如此。对于像
DataFilling
这样的受控组件,只调度最终状态,因此onChange
事件将在本地状态中保存值,然后onBlur
事件将结果调度到reducer。尽可能限制声明新变量,因此在reducer中您不需要
stateCopy
、将reducer初始状态设为
const
变量,您不希望覆盖它。在CCD_ 19中,第一部分将是数字,但第二部分将是空字符串。因为一致性和防止未来的错误使两者相同。此外,您还可以在将
size
调度到reducer之前进行此验证。
希望所有这些建议将有助于避免未来的错误
我不得不做深度复制
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
}
}