首页 > 解决方案 > React 和 redux 工具包:如何​​添加从拖放事件中获取数据的 reducer

问题描述

对 React 和 redux 来说非常新。我正在尝试向我的 React 应用程序添加文件拖放功能,但正在努力使用 redux 工具包的 createSlice 函数来解决这个问题。

我不断收到'TypeError:无法读取未定义的属性'fileList'。我认为这是因为我在下面的 searchSlice.js 中弄乱了 addFilesToList 减速器。

任何帮助将不胜感激。请在下面查看我的代码:

searchSlice.js

import { createSlice } from '@reduxjs/toolkit'


export const searchSlice = createSlice({
    name:'search',
    initialState: {
        fileList: [],
        inDropZone: false, 
         
    },

    reducers: {

        addToDropZone: (state) => {
            return state.inDropZone = true
        }
        ,
        
        addFilesToList: (state, e) => {
            return state.fileList = [...e.dataTransfer.files]
        }
    }
})

export const { addToDropZone, addFilesToList } = searchSlice.actions

export default searchSlice.reducer

拖放.js

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { addToDropZone, addFilesToList } from './searchSlice.js'
import DragArea from './DragArea.js'
import TableArea from './TableArea.js'

//import img from './components/images/drag.PNG'//


const DragDrop = (props) => {

    const files = useSelector((state) => state.searchSlice.fileList)
    const inDropZone = useSelector((state) => state.searchSlice.inDropZone)
    const dispatch = useDispatch()
    //const { data, dispatch } = props//


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

        dispatch(addToDropZone());
    };
    const handleDragLeave = (e) => {
        e.preventDefault();
        e.stopPropagation();
    };
    const handleDragOver = (e) => {
        e.preventDefault();
        e.stopPropagation();
        e.dataTransfer.dropEffect = 'copy';
        dispatch(addToDropZone());
    };
    const handleDrop = (e) => {
        e.preventDefault();
        e.stopPropagation();

        dispatch(addFilesToList());
        dispatch(addToDropZone());

        if (files && files.length > 0) {
            const existingFiles = files.map(f => f.name)
            files = files.filter(f => !existingFiles.includes(f.name))


        }

    };


    if (inDropZone === true && files.length === 0) {
        return(
                <div className = "drag-and-drop" 
                    onDrop={handleDrop}
                    onDragOver= {handleDragOver}
                    onDragEnter={handleDragEnter}
                    onDragLeave={handleDragLeave}>
                    <DragArea  />
                </div>
        )
    } else {
        return(
            <div className = "table-area" 
                onDrop={handleDrop}
                onDragOver= {handleDragOver}
                onDragEnter={handleDragEnter}
                onDragLeave={handleDragLeave}>
                <TableArea data = {files} />
        </div>
        )
    } 
}


export default DragDrop;

标签: javascriptreactjsreact-reduxredux-toolkitredux-reducers

解决方案


addFilesToList reducer 中的类型e是 PayloadAction。这意味着它的形状是这样的:

{
  type: “search/addFilesToList”,
  payload: valueYouPassToActionCreator
}

valueYouPassToActionCreator 是您在调度它时传递给 addFilesToList 操作创建者的任何内容,例如:

dispatch(addFilesToList(valueYouPassToActionCreator))

但是,您正在做:

dispatch(addFilesToList())

这意味着您的 PayloadAction 上的 .payload 属性未定义。简而言之,您需要将一些东西传递给动作创建者。


推荐阅读