javascript - 将数组从一个 UseState 传递到另一个 UseState

标签 javascript reactjs arrays react-dnd

我目前正在尝试弄清楚如何跨两个不同的组件将数组从一个 useState 对象传递到另一个 useState 对象。在我的第一个 useState 中,我有一个名为 imagesOriginal 的数组,该数组动态填充各种不同图像的文件路径,如下所示:

[
    "https://source.unsplash.com/WLUHO9A_xik/900x900",
    "https://source.unsplash.com/R4K8S77qtwI/900x900",
    "https://source.unsplash.com/jJGc21mEh8Q/900x900"
]

在我的 App.js 中,我像这样构建它。

import React, { useCallback, useState } from 'react';
import ShowImage from './ShowImage.jsx';
import DropBox from './DropBox.js';

function App() {
    const [imagesOriginal, setImages] = useState([]);

    const onDrop = useCallback((acceptedFiles) => {
        acceptedFiles.map((file, index) => {
            const reader = new FileReader();

            reader.onload = function (e) {
                setImages((prevState) => [
                    ...prevState,
                    { id: index, src: e.target.result },
                ]);
            };

            reader.readAsDataURL(file);
            return file;
        });
    }, []);

    return (
        <div className="App">
            <div class="parent">
                <div>
                    <h3>Originals</h3>
                    <DropBox onDrop={onDrop} />
                    <ShowImage images={imagesOriginal}/>
                </div>
            </div>
        </div>
    );
}

export default App;

主要问题出现在 ShowImage.jsx 中,我想将图像数组传递给另一个 useState,因为我需要使用数组和 setItems 对数组进行排序新订单。

import React, { useState } from 'react';
import {
    DndContext,
    closestCorners,
    MouseSensor,
    TouchSensor,
    DragOverlay,
    useSensor,
    useSensors,
} from '@dnd-kit/core';
import "./ShowImage.css"
import {arrayMove, SortableContext} from '@dnd-kit/sortable';
import {SortablePhoto} from './SortablePhoto.jsx';

const ShowImage = ({images}) => {

    const [items, setItems] = useState([]);
    setItems([...images]);
    const [activeId, setActiveId] = useState(null);
    const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));

    return(
        <div class="scroll">
            <DndContext
                sensors={sensors}
                collisionDetection={closestCorners}
                onDragStart={handleDragStart}
                onDragOver={handleDragOver}
                onDragEnd={handleDragEnd}
                onDragCancel={handleDragCancel}
            >
                <SortableContext items={items} strategy={() => {}}>
                    <div columns={1}
                        style={{
                        display: "grid",
                        gridAutoRows: `100px`,
                        gridGap: 10
                        }}
                    >
                        {items.map((url, index) => (
                            <SortablePhoto key={url.src} url={url.src} index={index}/>
                        ))}
                    </div>
                </SortableContext>
            </DndContext>
        </div>
    );

    function handleDragStart(event) {
        setActiveId(event.active.id);
    }
    
    function handleDragOver(event) {
        const {active, over} = event;
    
        if (active.id !== over.id) {
          setItems((items) => {
            const oldIndex = items.indexOf(active.id);
            const newIndex = items.indexOf(over.id);
    
            return arrayMove(items, oldIndex, newIndex);
          });
        }
    }
    
    function handleDragEnd(event) {
        setActiveId(null);
    }
    
    function handleDragCancel() {
        setActiveId(null);
    }
};

export default ShowImage;

我尝试使用行 setItems([...images]); 来尝试传递新项目,以及 const [items, setItems] = useState( images);,但它似乎永远不会更新 items 数组。我可能正在做一些非常愚蠢的事情,但任何帮助将不胜感激。

最佳答案

您可以在 App 组件中创建一个函数来包装您的 setItems 状态修饰符,并将该函数作为 prop 传递给嵌套的 ShowImage您可以使用它来操纵状态的组件。这样您就不需要维护 2 个不同的状态。

// App.js

function App() {
    const [imagesOriginal, setImages] = useState([]);
    const setImagesWrapper = useCallback(val => {
      setImages(val);
    }, [setImages]);
    //...

    return (
        <div className="App">
            <div class="parent">
                <div>
                    <h3>Originals</h3>
                    <DropBox onDrop={onDrop} />
                    <ShowImage 
                      images={imagesOriginal} 
                      setImages={setImagesWrapper}
                    />
                </div>
            </div>
        </div>
    );
}

export default App;
// ShowImage.js

const ShowImage = ({ images, setImages }) => {
    const [activeId, setActiveId] = useState(null);
    const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));
    // ...
};

export default ShowImage;

关于javascript - 将数组从一个 UseState 传递到另一个 UseState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73437514/

相关文章:

javascript - Js点击属性不适用于js加载的html

reactjs - 鼠标悬停事件触发的测试样式

reactjs - 为什么在尝试渲染变量中的组件时会出错?

php - PDO 数组中的重复值

javascript - Bootstrap Vue 可编辑表格列

javascript - 功能组件中的默认功能 Prop

javascript - 将引号中的短语视为 JavaScript 中的单词

javascript - 将 data-id 传递到 bootstrap 模式而不使用 jquery

javascript - 如何使用 jQuery 中的 inArray 比较两个数组中特定键的值

ios - 从 url 下载数据时等待填充表格 View