【问题标题】:Update State Array using Hooks (ReactJS)使用 Hooks (ReactJS) 更新状态数组
【发布时间】:2021-10-16 01:27:09
【问题描述】:

在我的代码中,我有以下状态数组和钩子:

const [rows, setRows] = React.useState([]);

所以在我的代码中,我想通过添加元素来更新 rows 数组。我遇到的麻烦是编写它,以便新元素不会替换旧元素,而只是添加它们。这是我试图做的:

const filesUploaded = event.target.files;
const tempArray = rows
let timestamp = new Date();
let month = timestamp.getMonth();
let year = timestamp.getFullYear();
let date = timestamp.getDate();
let displayDate = month + "/" + date + "/" + year

for(var i = 0; i < filesUploaded.length; i++) {
    let newElement = {id: i + 1,
                      filename: filesUploaded[i].name,
                      size: filesUploaded[i].size / 1000000,
                     date: displayDate }
    tempArray.push(newElement)
}
setRows(...tempArray);

所以它的工作方式是变量filesUploaded是一个数组,存储用户上传的文件。然后我创建了一个变量tempArray,它存储了行中的所有信息,然后你将filesUploaded中的每个元素一一添加到tempArray。然后在最后,将“行”状态设置为等于 tempArray,因为 tempArray 将包含前一个状态以及新状态的所有信息。

问题是每次我尝试这样做时,都会遇到以下错误:

TypeError: can't define array index property past the end of an array with non-writable length

这发生在“tempArray.push(newElement)”行(代码的倒数第三行)。

有没有人知道如何解决这个问题或通过向行状态添加元素来更新行状态,而不是使用钩子覆盖它?

【问题讨论】:

    标签: javascript arrays reactjs react-hooks


    【解决方案1】:

    不要分配tempArray = rows;

    tempArray = [...rows];

    tempArray.push(something);

    setRows(tempArray);

    状态不应该被直接改变

       tempArray = rows;
       tempArray.push(something)
    

    【讨论】:

      【解决方案2】:

      试试这个

      const temp = []
      for(var i = 0; i < filesUploaded.length; i++) {
          let newElement = {id: i + 1,
                            filename: filesUploaded[i].name,
                            size: filesUploaded[i].size / 1000000,
                           date: displayDate }
          temp.push(newElement)
      }
      
      setRows([...rows,...temp])
      

      【讨论】:

      • 只需将 setRows(...tempArray) 更改为 setRows([...tempArray]);
      • 因为你的代码意味着 setRows(element1,element2,element3,......) 不是一个数组
      【解决方案3】:

      由于数组是通过引用复制的,如果需要复制,请使用扩展运算符:

      tempArray = [...rows];
      

      但我不会这样做。我会将 newElement 直接添加到行中:

      setRows([...rows, newElement]);
      

      (您必须为此在全局范围内定义 newElement)。

      【讨论】:

        【解决方案4】:

        rows 是只读的

        const [rows, setRows] = React.useState([]);    
        

        这里是引用赋值,所以也是只读的。

        const tempArray = rows //referenced and readonly too
        
        for(var i = 0; i < filesUploaded.length; i++) {
            let newElement = {id: i + 1,
                              filename: filesUploaded[i].name,
                              size: filesUploaded[i].size / 1000000,
                             date: displayDate }
            tempArray.push(newElement) //can't use .push with readonly array
        }
        

        相反,您应该使用扩展运算符

        const tempArray = [...rows] //tempArray is a tottaly new array.
        

        现在以这种方式将新数组分配给状态

        setRows([...tempArray]);
        

        您的代码已修复

        const [rows, setRows] = React.useState([]);
        const filesUploaded = event.target.files;
        const tempArray = [...rows];
        let timestamp = new Date();
        let month = timestamp.getMonth();
        let year = timestamp.getFullYear();
        let date = timestamp.getDate();
        let displayDate = month + "/" + date + "/" + year
        
        for(var i = 0; i < filesUploaded.length; i++) {
            let newElement = {id: i + 1,
                              filename: filesUploaded[i].name,
                              size: filesUploaded[i].size / 1000000,
                             date: displayDate }
            tempArray.push(newElement)
        }
        setRows([...tempArray]);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-19
          • 2021-03-16
          • 1970-01-01
          • 2020-09-24
          • 2018-11-04
          相关资源
          最近更新 更多