Javascript 道具被状态更改覆盖?

Javascript 道具被状态更改覆盖?,javascript,reactjs,typescript,react-hooks,Javascript,Reactjs,Typescript,React Hooks,我在代码中遇到了一个奇怪的错误,我正在努力理解原因 简而言之,我传递给功能组件的道具似乎正在被状态更改覆盖(这肯定不会传播到父级)。我猜这是因为我在创建新对象时做了一些错误的事情,然后这些对象被用来更新状态,但是我很难知道在哪里 我使用的是react select,它的change函数触发了这个bug。我不认为这本身就是问题所在,因为我在项目的其他地方使用过它,没有遇到这个错误 以下是我的代码的精简版本(已删除导入): 接口IPropertyValue{ 字段1:编号; 字段2:编号; 字段3:

我在代码中遇到了一个奇怪的错误,我正在努力理解原因

简而言之,我传递给功能组件的道具似乎正在被状态更改覆盖(这肯定不会传播到父级)。我猜这是因为我在创建新对象时做了一些错误的事情,然后这些对象被用来更新状态,但是我很难知道在哪里

我使用的是react select,它的change函数触发了这个bug。我不认为这本身就是问题所在,因为我在项目的其他地方使用过它,没有遇到这个错误

以下是我的代码的精简版本(已删除导入):

接口IPropertyValue{
字段1:编号;
字段2:编号;
字段3:编号;
字段4:字符串;
}
接口INestedPropertyType{
系统属性?:IPropertyValue;
}
接口IPropertyType{
当前:INestedPropertyType;
所需:INestedPropertyType;
}
接口i组件道具{
currentProperty:IPropertyType;
}
导出功能组件(passedProps:IDynamicPropsType){
const props=作为IComponentProps传递的props;
const[propName,setPropName]=useState(props.currentProperty);
const editValue=(typeOfProperty:'current'|'desired',newValue:string)=>{
让existingPropName={…propName}作为IPropertyType;//从现有对象创建一个新对象
让alteredPropName={}作为ISystemProperty;//我们稍后根据typeOfProperty重新分配它
if(typeOfProperty===“当前”){
if(existingPropName.current.systemProperty){
alteredPropname={…existingPropName.current.systemProperty}作为IPropertyValue;
}否则{
existingPropName.current.systemProperty={}作为IPropertyValue;
alteredPropName={}作为IPropertyValue;
}
}else if(typeOfProperty===‘所需’){
如果(existingPropName.desired.systemProperty){//可能未定义。。。
//定义后,使用现有值为其创建新对象
existingPropName={…existingPropName.desired.systemProperty}作为IPropertyValue;
}否则{
//未定义,请为其创建空对象
existingLineage.desired.systemProperty={}作为IPropertyValue;
alteredPropName={}作为IPropertyValue;
}
}
const newValues=newValue.split(“|”);//来自选择选项;它是一个由“|”符号分隔的字符串。它的长度始终为4个值。
如果(newValues.length==4){
alteredPropName={
…更改了名称,
字段1:parseInt(新值[0],10),
字段2:parseInt(newValues[1],10),
字段3:parseInt(newValues[2],10),
字段4:新值[3]
}
}
//使用更新的对象更新相关属性
if(typeOfProperty===“当前”){
existingPropName.current.systemProperty=alteredPropName;
}else if(typeOfProperty===‘所需’){
existingPropName.desired.systemProperty=alteredPropName;
}
//更新状态
setPropName(现有谱系);
}
//奇怪的是,调用editValue函数后,“props”会发生变化,即使它应该从父组件传入并保持不变(除了将其强制转换为IComponentProps)
控制台日志(道具);
返回(
{
editValue('current',selectedOption.value);
}}
/>
{
editValue(“所需”,选择选项.value);
}}
/>
);
}

代码中有一些奇怪的部分,例如将
passedProps
转换为
props
,但它们的存在是有原因的-父组件是一个在多个其他组件之间共享的包装器。

是的,你是对的。您的道具正在被覆盖,因为您正在将它们直接传入

useState(props.currentProperty)
在Javascript中,对象是引用类型。调用editValue将导致更新嵌套对象

在将道具传递给
useState
之前,您可以创建道具的深度副本。简单的方法是使用
JSON.stringify
JSON.parse

const [propName, setPropName] = useState(JSON.parse(JSON.stringify(props.currentProperty)));

当然我尝试将其强制转换为一个新对象(代码中未显示),但我只使用了浅拷贝,而不是深拷贝。我的错。
const [propName, setPropName] = useState(JSON.parse(JSON.stringify(props.currentProperty)));