Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.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 即使在useEffect中设置之后,状态也返回空数组_Javascript_Reactjs - Fatal编程技术网

Javascript 即使在useEffect中设置之后,状态也返回空数组

Javascript 即使在useEffect中设置之后,状态也返回空数组,javascript,reactjs,Javascript,Reactjs,我在SO上看到过类似的问题,但无法确定我遇到的问题 我有一个useState变量,在第一次加载时在useEffect中设置。然后,在很晚的时间,触发一个事件,在事件中我检查变量的值,它总是一个空数组[]。但是,我添加了第二个useEffect来跟踪状态变量中的更改,我看不到它在哪里被清空。下面是一些代码来突出我的问题: import React, { useState, useEffect } from "react"; import { DragAndDrop } from

我在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;

import React,{useState,useffect}来自“React”;
从“./components”导入{DragAndDrop};
const AddKidPage=()=>{
const[files,setFiles]=useState([]);
useffect(()=>{
变量f=[
“nice.pdf”,
“verycool.jpg”,
“惊人的.png”,
“好东西,mp3”,
“谢谢你,博士”,
];
设置文件(f);
}, []);
useffect(()=>{
console.log(文件);
},[文件];
常量handleDrop=(新文件)=>{
让fileList=文件;
//此处文件=[]
对于(var i=0;i(
{file}
))}
);
};
导出默认的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;



从“React”导入React,{useState,useffect};
从“样式化组件”导入样式化;
const dragandrop=({handleDrop:externalDrop,children})=>{
const[drag,setDrag]=useState(false);
常量[dragCounter,setDragCounter]=使用状态(0);
常量句柄=(e)=>{
e、 预防默认值();
e、 停止传播();
};
常数handleDragIn=(e)=>{
e、 预防默认值();
e、 停止传播();
设置dragCounter(dragCounter+1);
if(e.dataTransfer.items&&e.dataTransfer.items.length>0){
setDrag(真);
}
};
常量句柄=(e)=>{
e、 预防默认值();
e、 停止传播();
设置dragCounter(dragCounter-1);
如果(拖动计数器-1==0){
setDrag(假);
}
};
常数handleDrop=(e)=>{
e、 预防默认值();
e、 停止传播();
setDrag(假);
如果(e.dataTransfer.files&&e.dataTransfer.files.length>0){
externalDrop(例如dataTransfer.files);
e、 dataTransfer.clearData();
setDragCounter(0);
}
};
useffect(()=>{
var div=document.getElementById(“draganddrop包装器”);
第5部分:附加列表(“dragenter”,handleDragIn);
第二部分:增补列表(“dragleave”,handleDragOut);
第二部分:增补列表(“dragover”,handleDrag);
第二部分添加的列表器(“下降”,手动下降);
return()=>{
第removeEventListener部分(“dragenter”,handleDragIn);
第removeEventListener部分(“dragleave”,handleDragOut);
部门removeEventListener(“dragover”,handleDrag);
第二部分:拆卸通风装置(“下降”,手动下降);
};
}, []);
返回(
{拖动&&(
到这里来
)}
{儿童}
);
};
const Wrapper=styled.div`
显示:内联块;
位置:相对位置;
.拖动鼠标悬停{
边框:灰色虚线4px;
背景:rgba(255,255,255,0.8);
位置:绝对位置;
排名:0;
底部:0;
左:0;
右:0;
z指数:9999;
.拖动覆盖{
位置:绝对位置;
最高:50%;
右:0;
左:0;
文本对齐:居中;
颜色:灰色;
字体大小:36px;
}
}
`;
导出默认DragAndDrop;

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

改变

let fileList = files;


更新

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

谢谢你的建议。我试过了,结果是一样的。我添加了以下代码:constfilelist=[…files];console.log(文件列表);我得到的输出是[]。尝试更改
constfilelist=[…文件]
to
let fileList=[…文件]不幸的是,let的行为是相同的。我已经修改了我的问题以包含其他组件。我不确定这是否应该归咎于它,但我想我会加上它。@BrianLegg您是说组件装载后第一次调用
handledrop
文件
数组是
控制台。在
//此处…
注释中将
记录为空?
dragandrop
组件将不相关,因为它不会直接与
文件
数组交互。你能在codesandbox上提供你的代码样本吗?
const handleDrop = useCallback((newFile) => {
    if (newFile.type === "image/png") {
        setFile(newFile.name);
    }
}, []);