Javascript Typescript-使用日期时更新对象数组失败
我有一个typescript函数,它接收一个“queryParameter”,然后从组件内的状态钩子遍历一组现有的queryParameter。如果它找到匹配的参数名,我希望它将queryParameters对象更新为常量“newQueryParams” 请注意,问题仅在使用“日期”查询参数时出现。所有代码示例都适用于其他类型(“getLatest”和“fundCode”)。此外,这不是日期对象相等的问题 功能(仅必要部分): 我已记录了各种位,以显示发生了什么: 如您所见,传入参数尝试将日期更改为21,但失败,尽管循环中存在匹配 我也尝试过使用深度副本:Javascript Typescript-使用日期时更新对象数组失败,javascript,reactjs,typescript,object,react-hooks,Javascript,Reactjs,Typescript,Object,React Hooks,我有一个typescript函数,它接收一个“queryParameter”,然后从组件内的状态钩子遍历一组现有的queryParameter。如果它找到匹配的参数名,我希望它将queryParameters对象更新为常量“newQueryParams” 请注意,问题仅在使用“日期”查询参数时出现。所有代码示例都适用于其他类型(“getLatest”和“fundCode”)。此外,这不是日期对象相等的问题 功能(仅必要部分): 我已记录了各种位,以显示发生了什么: 如您所见,传入参数尝试将日期
const deepCopyFunction = (inObject: any) => {
let outObject: any, value, key
if (typeof inObject !== "object" || inObject === null) {
return inObject // Return the value if inObject is not an object
}
// Create an array or object to hold the values
outObject = Array.isArray(inObject) ? [] : {}
for (key in inObject) {
value = inObject[key]
// Recursively (deep) copy for nested objects, including arrays
outObject[key] = deepCopyFunction(value)
}
return outObject
}
const handleQueryParameterChange = (
queryParameter: DataProductQueryParameter
) => {
const queryParametersCopy = deepCopyFunction(queryParameters);
const deepCopyQueryParam = {...queryParameter};
console.log("existing parameters copy: ", queryParametersCopy)
console.log("incoming new parameter: ", queryParameter)
console.log("incoming parameter deep copy: ", deepCopyQueryParam);
const newQueryParams = queryParametersCopy.map((param, i) => {
console.log("loop: " + i);
if(deepCopyQueryParam.name === param.name) {
console.log("match");
param.suggestedValue = deepCopyQueryParam.suggestedValue;
}
return param;
});
console.log("new query params: ", newQueryParams);
产生了同样的结果:
我还尝试在获得匹配项时仅切换整个对象,而不是仅编辑属性:
const handleQueryParameterChange = (queryParameter: DataProductQueryParameter) => {
console.log("existing parameters: ", queryParameters)
console.log("incoming new parameter: ", queryParameter)
const newQueryParams = queryParameters.map(param => {
return queryParameter.name === param.name ? queryParameter : param;
});
console.log("new query params: ", newQueryParams);
…这也不起作用/下面的屏幕截图概述了输出,但也注意到了“传入新参数”中标题和扩展对象之间的差异。我已经见过几次了,虽然堆栈溢出告诉我它是控制台的异步性质,但我不明白为什么它会发生在代码中
请再次注意,问题仅出现在“日期”查询参数中。所有代码示例都适用于其他类型(“getLatest”和“fundCode”)
更新
我已经实现了其中一个建议的改进,但仍然没有得到正确的输出
下面是更多的代码,包括一个状态钩子和一个效果钩子,以及新的实现:
const [queryParameters, setQueryParameters] = useState<DataProductQueryParameter[]>(dataProductQueryParameters ?? []);
useEffect(() => {
console.log("effect called: ", queryParameters)
}, [queryParameters])
const handleQueryParameterChange = (queryParameter: DataProductQueryParameter) => {
if(queryParameter.name === "getLatest") {
setDatePickerDisabled(!datePickerDisabled);
}
const matchIndex = queryParameters.findIndex(param => queryParameter.name === param.name);
const queryParametersCopy = JSON.parse(JSON.stringify(queryParameters));
if (matchIndex !== -1) {
const suggestedValue = queryParameter.suggestedValue;
queryParametersCopy[matchIndex] = { ...queryParametersCopy[matchIndex], suggestedValue}
}
console.log("new query params: ", queryParametersCopy);
setQueryParameters(queryParametersCopy);
};
常量[queryParameters,setQueryParameters]=useState(dataProductQueryParameters???[]);
useffect(()=>{
log(“调用的效果:”,queryParameters)
},[queryParameters])
常量handleQueryParameterChange=(queryParameter:DataProductQueryParameter)=>{
if(queryParameter.name==“getLatest”){
setDatePickerDisabled(!datePickerDisabled);
}
const matchIndex=queryParameters.findIndex(param=>queryParameter.name==param.name);
const queryParametersCopy=JSON.parse(JSON.stringify(queryParameters));
如果(匹配索引!=-1){
const suggestedValue=queryParameter.suggestedValue;
QueryParameterScope[matchIndex]={…QueryParameterScope[matchIndex],suggestedValue}
}
log(“新查询参数:”,queryParameterScope);
设置查询参数(查询参数);
};
组件加载时状态挂钩设置成功。当我调用handleChange函数时,我的调试器显示它成功地更新了新数组(newQueryParams)
当调用setQueryParameters来更新状态挂钩时,会出现问题。调用useffect钩子时,它似乎触发得很好。但是我的调试器和控制台都显示更新的数组上的suggestedValue字段没有得到更新
同样,对于其他字段(getLatest和fundCode),这也非常有效,因此逻辑是合理的,钩子用于设置新值,但是日期不会更新
谢谢您最初的代码运行得非常好。如果运行以下代码段,您将看到最终的
新查询参数
日志显示suggestedValue
属性已成功更新:
常量查询参数=[{
名称:'测试',
建议值:“2021-03-23”
},
{
名称:“foobar”,
建议值:“2022-03-23”
}
]
常量handleQueryParameterChange=(queryParameter)=>{
log(“来自状态挂钩的现有参数:”,queryParameters)
log(“函数的传入参数:”,queryParameter)
const newQueryParams=queryParameters.map((param,i)=>{
console.log(“循环:+i”);
if(queryParameter.name==param.name){
控制台日志(“匹配”);
param.suggestedValue=queryParameter.suggestedValue;
}
返回参数;
});
log(“新查询参数:”,newQueryParams);
}
handleQueryParameterChange({
名称:'测试',
建议值:“2021-03-21”
})
我试图用一个小组件重现您的设置,该组件有两种状态,就像您在更新的问题中所显示的一样。此代码(重用对象交换)似乎正确更新了queryParameters
。您是否可以尝试使用setQueryParameters(prevQueryParameters=>…)
重用该零件,以查看它是否解决了您的问题
import React, { FC, Fragment, useCallback, useEffect, useState } from 'react';
interface DataProductQueryParameter {
name: string;
parameterType: string;
format: string;
description: string;
suggestedValue: string;
}
const dataProductQueryParameters: DataProductQueryParameter[] = [
{
name: 'test',
format: '',
description: '',
parameterType: '',
suggestedValue: '',
},
{
name: 'other',
format: '',
description: '',
parameterType: '',
suggestedValue: '',
},
];
export const StackOverflow: FC = () => {
const [datePickerDisabled, setDatePickerDisabled] = useState(false);
const [queryParameters, setQueryParameters] = useState<DataProductQueryParameter[]>(
dataProductQueryParameters,
);
useEffect(() => {
console.log('effect called: ', queryParameters);
}, [queryParameters]);
const handleQueryParameterChange = useCallback(
(queryParameter: DataProductQueryParameter) => {
if (queryParameter.name === 'getLatest') {
setDatePickerDisabled(prevDatePickerDisabled => !prevDatePickerDisabled);
}
setQueryParameters(prevQueryParameters =>
prevQueryParameters.map(param => {
if (param.name === queryParameter.name) {
return queryParameter;
}
return param;
}),
);
},
[setQueryParameters, setDatePickerDisabled],
);
return (
<Fragment>
<button
onClick={() =>
handleQueryParameterChange({
name: 'test',
description: 'updated',
format: 'updated',
parameterType: 'updated',
suggestedValue: 'updated',
})
}
>
Update !
</button>
</Fragment>
);
};
import React,{FC,Fragment,useCallback,useffect,useState}从'React'导入;
接口DataProductQueryParameter{
名称:字符串;
参数类型:字符串;
格式:字符串;
描述:字符串;
suggestedValue:字符串;
}
常数dataProductQueryParameters:DataProductQueryParameter[]=[
{
名称:'测试',
格式:“”,
说明:“”,
参数类型:“”,
建议值:“”,
},
{
名称:'其他',
格式:“”,
说明:“”,
参数类型:“”,
建议值:“”,
},
];
导出常量堆栈溢出:FC=()=>{
const[datePickerDisabled,setDatePickerDisabled]=useState(false);
常量[queryParameters,setQueryParameters]=useState(
dataProductQueryParameters,
);
useffect(()=>{
log('effect called:',queryParameters);
},[查询参数];
const handleQueryParameterChange=useCallback(
(queryParameter:DataProductQueryParameter)=>{
if(queryParameter.name=='getLatest'){
setDatePickerDisabled(prevDatePickerDisabled=>!prevDatePickerDisabled);
}
setQueryParameters(prevQueryParameters=>
prevQueryParameters.map(参数=>{
if(param.name==queryParameter.name){
返回查询参数;
}
返回参数;
}),
);
},
[setQueryParameters,setDatePickerDisabled],
);
返回(
哈
import React, { FC, Fragment, useCallback, useEffect, useState } from 'react';
interface DataProductQueryParameter {
name: string;
parameterType: string;
format: string;
description: string;
suggestedValue: string;
}
const dataProductQueryParameters: DataProductQueryParameter[] = [
{
name: 'test',
format: '',
description: '',
parameterType: '',
suggestedValue: '',
},
{
name: 'other',
format: '',
description: '',
parameterType: '',
suggestedValue: '',
},
];
export const StackOverflow: FC = () => {
const [datePickerDisabled, setDatePickerDisabled] = useState(false);
const [queryParameters, setQueryParameters] = useState<DataProductQueryParameter[]>(
dataProductQueryParameters,
);
useEffect(() => {
console.log('effect called: ', queryParameters);
}, [queryParameters]);
const handleQueryParameterChange = useCallback(
(queryParameter: DataProductQueryParameter) => {
if (queryParameter.name === 'getLatest') {
setDatePickerDisabled(prevDatePickerDisabled => !prevDatePickerDisabled);
}
setQueryParameters(prevQueryParameters =>
prevQueryParameters.map(param => {
if (param.name === queryParameter.name) {
return queryParameter;
}
return param;
}),
);
},
[setQueryParameters, setDatePickerDisabled],
);
return (
<Fragment>
<button
onClick={() =>
handleQueryParameterChange({
name: 'test',
description: 'updated',
format: 'updated',
parameterType: 'updated',
suggestedValue: 'updated',
})
}
>
Update !
</button>
</Fragment>
);
};