Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Typescript-使用日期时更新对象数组失败_Javascript_Reactjs_Typescript_Object_React Hooks - Fatal编程技术网

Javascript Typescript-使用日期时更新对象数组失败

Javascript Typescript-使用日期时更新对象数组失败,javascript,reactjs,typescript,object,react-hooks,Javascript,Reactjs,Typescript,Object,React Hooks,我有一个typescript函数,它接收一个“queryParameter”,然后从组件内的状态钩子遍历一组现有的queryParameter。如果它找到匹配的参数名,我希望它将queryParameters对象更新为常量“newQueryParams” 请注意,问题仅在使用“日期”查询参数时出现。所有代码示例都适用于其他类型(“getLatest”和“fundCode”)。此外,这不是日期对象相等的问题 功能(仅必要部分): 我已记录了各种位,以显示发生了什么: 如您所见,传入参数尝试将日期

我有一个typescript函数,它接收一个“queryParameter”,然后从组件内的状态钩子遍历一组现有的queryParameter。如果它找到匹配的参数名,我希望它将queryParameters对象更新为常量“newQueryParams”

请注意,问题仅在使用“日期”查询参数时出现。所有代码示例都适用于其他类型(“getLatest”和“fundCode”)。此外,这不是日期对象相等的问题

功能(仅必要部分):

我已记录了各种位,以显示发生了什么:

如您所见,传入参数尝试将日期更改为21,但失败,尽管循环中存在匹配

我也尝试过使用深度副本:

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>
  );
};