数组值在 useEffect 钩子中更改

Array values change inside useEffect hook

提问人:Arnab 提问时间:11/17/2023 最后编辑:Drew ReeseArnab 更新时间:11/18/2023 访问量:49

问:

我有一个文件上传组件,每当添加文件时,如果没有任何错误,我们都会尝试上传它。如果遇到任何错误(类型/大小/网络等问题),我们会在文件对象中设置错误键,并设置收到的错误类型。

就我而言,问题是每当更新 Files 数组时,我都会有一个 useEffect 钩子来更新错误状态,以呈现错误组件。

这是钩子:useEffect

useEffect(() => {
    if (files.length === 0) {
        setError?.(false);
    }

    console.log("FilesArray before filter =>", files);

    const errorFiles = files.filter((file, index) => {
        console.log("FilesArray =>", file, `File at index = ${index}`, file, "fileError =>", file.error);
        return file.error;
    });

    console.log("FilesArray after filter =>", files, "ErrorFiles Array =>", errorFiles);

    setError?.(errorFiles.length !== 0, errorFiles);
}, [files]);

我也尝试在过滤器函数中添加控制台日志,问题是在过滤器之前和之后记录的文件数组在错误键中具有“technicalError”,而过滤器方法中记录的文件数组没有。

下面是控制台中的快照。

enter image description here

JavaScript 反应JS

评论

0赞 nullptr 11/17/2023
这看起来像是如何不使用 .是什么阻止您在设置文件时设置错误?useEffects
0赞 Thomas 11/17/2023
什么?它真的是一个带有动态参数的可为空函数吗?setError
0赞 CodeThing 11/17/2023
你能为此创建一个沙盒吗?
0赞 Drew Reese 11/18/2023
如果我不得不冒昧地猜测,我会说你在其他地方有一些代码正在改变这个数组引用,不管它是什么。你能编辑以发布你正在使用的所有相关代码的完整最小可重现示例吗?files
0赞 Arnab 11/22/2023
对不起,我将无法再共享任何代码。我们实际上发现了这个问题,正如@DrewReese指出的那样,“您在其他地方有一些代码正在改变此文件数组”。我们错误地改变了状态。类似的事情:我遇到了 react.dev/learn/......创建一个新数组并使用它解决了我的问题setFiles(_files => { let index = 0; const file = _files[index]; file.error = "randomError"; _files[index] = file; return _files; })const tempArr = [..._files];

答:

-1赞 Konstantinos K. 11/17/2023 #1

通过创建浅拷贝 (filesCopy),确保对 useEffect 钩子内 files 数组的稳定副本进行操作。这样可以防止由关闭引起的意外行为,并确保准确过滤有错误的文件。

useEffect(() => {
    if (files.length === 0) {
        setError?.(false);
    }

    const filesCopy = [...files]; // Create a shallow copy of the files array

    const errorFiles = filesCopy.filter((file, index) => file.error);

    setError?.(errorFiles.length !== 0, errorFiles);
}, [files]);

评论

0赞 Thomas 11/17/2023
你在这里期待什么样的意外行为? 在不更改旧数组的情况下创建一个新数组,因此从某种意义上说,它已经是一个浅层的,不是副本,而是子集。什么是数组的“不准确过滤”,这种浅拷贝如何帮助解决这个问题?Array#filter()