当前位置: 首页 > 知识库问答 >
问题:

状态返回一个空数组,即使在use中设置

羊冠玉
2023-03-14

我在SO上看到过类似的问题,但无法确定我遇到的问题。

我有一个useState变量,在第一次加载时在useEffect中设置。然后,在很晚的时间触发一个事件,在事件中我检查变量的值,它总是一个空数组[]。但是,我添加了第二个useEffect来跟踪状态变量中的更改,我看不到它在哪里被清空。下面是一些代码来突出我的问题:

import React, { useState, useEffect } from "react";
import { DragAndDrop } from "../components";

const AddKidPage = () => {
  const [files, setFiles] = useState([]);

  useEffect(() => {
    var f = [
      "nice.pdf",
      "verycool.jpg",
      "amazing.png",
      "goodstuff.mp3",
      "thankyou.doc",
    ];

    setFiles(f);
  }, []);

  useEffect(() => {
    console.log(files);
  }, [files]);

  const handleDrop = (newFiles) => {
    let fileList = files;

    // HERE FILES = []

    for (var i = 0; i < newFiles.length; i++) {
      if (!newFiles[i].name) return;
      fileList.push(newFiles[i].name);
    }

    setFiles(fileList);
  };

  return (
    <main>
      <DragAndDrop handleDrop={handleDrop}>
        <div style={{ height: 300, width: 250 }}>
          {files.map((file, i) => (
            <div key={i}>{file}</div>
          ))}
        </div>
      </DragAndDrop>
    </main>
  );
};

export default AddKidPage;

我在跟踪useffect的文件中有1个console.log。以下是组件安装时的输出:

[]

[“nice.pdf”、“verycool.jpg”、“sapping.png”、“goodstuff.mp3”、“thankyou.doc”]

这是有道理的-我初始化数组为空,然后我立即填充它的值,然后触发第二个输出。但是,这里是输出后,我删除一个文件(这会导致handleDrop()执行):

[“newFile.png”]

如您所见,所有其他值都被删除。我在代码“herefiles=[]”中的注释演示了文件useState在何处仍然为空,即使我的输出显示它已填充。useEffect不会第二次输出空数组,所以它在哪里被清空?我检索的值是否错误?非常感谢您对这个谜团的任何帮助。我选择不显示DragAndDrop组件的代码,但它看起来很可靠,并在正确的时间使用正确的值调用handleDrop方法。

编辑:

虽然DragAndDrop看起来很可靠,但这可能是我如何调用传入函数的某种问题。。。或者我对{children}的使用。我不确定。下面是DragAndDrop的代码,它完成了这个组件。


import React, { useState, useEffect } from "react";
import styled from "styled-components";

const DragAndDrop = ({ handleDrop: externalDrop, children }) => {
  const [drag, setDrag] = useState(false);
  const [dragCounter, setDragCounter] = useState(0);

  const handleDrag = (e) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleDragIn = (e) => {
    e.preventDefault();
    e.stopPropagation();

    setDragCounter(dragCounter + 1);
    if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
      setDrag(true);
    }
  };

  const handleDragOut = (e) => {
    e.preventDefault();
    e.stopPropagation();

    setDragCounter(dragCounter - 1);
    if (dragCounter - 1 === 0) {
      setDrag(false);
    }
  };

  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();

    setDrag(false);
    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      externalDrop(e.dataTransfer.files);
      e.dataTransfer.clearData();
      setDragCounter(0);
    }
  };

  useEffect(() => {
    var div = document.getElementById("draganddrop-wrapper");

    div.addEventListener("dragenter", handleDragIn);
    div.addEventListener("dragleave", handleDragOut);
    div.addEventListener("dragover", handleDrag);
    div.addEventListener("drop", handleDrop);

    return () => {
      div.removeEventListener("dragenter", handleDragIn);
      div.removeEventListener("dragleave", handleDragOut);
      div.removeEventListener("dragover", handleDrag);
      div.removeEventListener("drop", handleDrop);
    };
  }, []);

  return (
    <Wrapper id="draganddrop-wrapper">
      {drag && (
        <div className="drag-hover">
          <div className="drag-overlay">
            <div>drop here</div>
          </div>
        </div>
      )}
      {children}
    </Wrapper>
  );
};

const Wrapper = styled.div`
  display: inline-block;
  position: relative;
  .drag-hover {
    border: dashed grey 4px;
    background: rgba(255, 255, 255, 0.8);
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    .drag-overlay {
      position: absolute;
      top: 50%;
      right: 0;
      left: 0;
      text-align: center;
      color: grey;
      font-size: 36px;
    }
  }
`;

export default DragAndDrop;


共有1个答案

穆乐逸
2023-03-14

这是因为您正在变异文件变量,而不是克隆它。

改变

let fileList = files;

const fileList = [...files];

使现代化

const handleDrop = useCallback((newFile) => {
    if (newFile.type === "image/png") {
        setFile(newFile.name);
    }
}, []);

代码沙盒

 类似资料:
  • 我是JPCAP的新手。我在用 eth0链路Encap:Ethernet HWaddr 18:A9:05:CB:8D:FB 上行广播多播MTU:1500度量:1个RX数据包:0个错误:0个丢弃:0个溢出:0帧:0个TX数据包:0个错误:0个丢弃:0个溢出:0载波:0个冲突:0个TX队列n:1000个RX字节:0(0.0B)TX字节:0(0.0B)中断:17 lo链接Encap:本地环回 inet A

  • 问题内容: 我已经尝试过使用并且都没有返回文档。是在返回一个空数组被返回。在这两种情况下也是如此。 这是我的联系: 这是我的架构: 我的查询在这里: 我可以将内容上传到数据库,并通过RockMongo进行查看,但之后无法获取它们。这是我第一次使用MongoDB,因此我认为我只是缺少一些基础知识。向正确方向的任何推动都是很棒的! 问题答案: 建立模型所绑定的集合的名称的调用,默认值为复数的小写模型名

  • 我在一个三元组中使用了< code>this.setState(),并试图找出它返回的内容。文档没有提供任何关于它返回什么的信息。

  • 在我的C程序中,我使用了一个带有以下参数的void函数:一个2D int数组、一个用于创建新动态数组的int指针和一个最后的int指针,该指针将保存函数内部发生的计数。因此,动态数组是使用malloc在函数中创建的,一切正常,直到调用函数后在main()中打印其元素。我得到的是垃圾,而不是我应该看到的数字。以下是功能代码:

  • 问题内容: 我有两个模型,用户模型和时间表,我想用$ lookup 和猫鼬把这两个模型结合起来。 用户(型号) 时间表(型号) 现在我的查询使用猫鼬: 用户汇总 我的查询结果是一个空的array(),如下所示: 查询结果: 我不知道为什么,但是查询结果是一个 空数组 ,我试图使用$ unwind和$ match,但也无法正常工作。 编辑: 用户集合 时间表的收集 问题答案: 猫鼬在创建时将集合名称

  • 我有一个类组件,它返回使用Redux存储完全填充的状态: 但是,当我将上面的类组件切换到下面的功能组件,以便可以在代码中使用ReactJS钩子时,状态始终为空。