[英]props being overwritten by state change?
我在我的代碼中遇到了一個奇怪的錯誤,我正在努力理解原因。
簡而言之,我傳遞給功能組件的道具似乎被 state 更改覆蓋(這絕對不會傳播到父級)。 我猜這是因為我在創建新對象時做錯了,然后這些新對象用於更新 state,但我很難知道在哪里。
我正在使用 react-select,這是觸發錯誤的更改 function 。 我不認為這本身就是問題所在,因為我在項目的其他地方使用過它並且沒有遇到這個錯誤。
這是我的代碼的精簡版本(已刪除導入):
interface IPropertyValue {
field1: number;
field2: number;
field3: number;
field4: string;
}
interface INestedPropertyType {
systemProperty?: IPropertyValue;
}
interface IPropertyType {
current: INestedPropertyType;
desired: INestedPropertyType;
}
interface IComponentProps {
currentProperty: IPropertyType;
}
export function Component(passedProps: IDynamicPropsType) {
const props = passedProps as IComponentProps;
const [propName, setPropName] = useState(props.currentProperty);
const editValue = (typeOfProperty: 'current' | 'desired', newValue: string) => {
let existingPropName = {...propName} as IPropertyType; // create a new object from existing one
let alteredPropName = {} as ISystemProperty; // we reassign this later on based on typeOfProperty
if(typeOfProperty === 'current') {
if(existingPropName.current.systemProperty) {
alteredPropname = {...existingPropName.current.systemProperty} as IPropertyValue;
} else {
existingPropName.current.systemProperty= {} as IPropertyValue;
alteredPropName= {} as IPropertyValue;
}
} else if (typeOfProperty=== 'desired') {
if(existingPropName.desired.systemProperty) { // could be undefined...
// is defined, create a new object for it using existing values
existingPropName= {...existingPropName.desired.systemProperty} as IPropertyValue;
} else {
// not defined, create empty object for it
existingLineage.desired.systemProperty= {} as IPropertyValue;
alteredPropName= {} as IPropertyValue;
}
}
const newValues = newValue.split('|'); // this comes from the select option; it's a string separated by '|' symbols. It will always be 4 values long.
if(newValues.length === 4) {
alteredPropName = {
...alteredPropName,
field1: parseInt(newValues[0], 10),
field2: parseInt(newValues[1], 10),
field3: parseInt(newValues[2], 10),
field4: newValues[3]
}
}
// update the relevant property with the updated object
if(typeOfProperty === 'current') {
existingPropName.current.systemProperty = alteredPropName;
} else if(typeOfProperty=== 'desired') {
existingPropName.desired.systemProperty = alteredPropName;
}
// update the state
setPropName(existingLineage);
}
// here's the weird part. 'props' is changed after the editValue function is called, even though it should be passed in from the parent component and left unchanged (apart from casting it to IComponentProps)
console.log(props);
return (<>
<Select
options={<options here>}
onChange={(selectedOption: ValueType<any>) => {
editValue('current', selectedOption.value);
}}
/>
<Select
options={<options here>}
onChange={(selectedOption: ValueType<any>) => {
editValue('desired', selectedOption.value);
}}
/>
</>);
}
代碼中有一些奇怪的部分,例如將passedProps
為props
,但它們的存在是有原因的 - 父組件是一個在多個其他組件之間共享的包裝器。
是的你是對的。 您的道具被覆蓋,因為您直接將它們傳遞
useState(props.currentProperty)
在 Javascript 中,對象是引用類型。 調用 editValue 將導致更新嵌套對象。
您可以在將道具傳遞給useState
之前創建道具的深層副本。 簡單的方法是使用JSON.stringify
和JSON.parse
const [propName, setPropName] = useState(JSON.parse(JSON.stringify(props.currentProperty)));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.