【问题标题】:Drag and drop functionality in React returns errosReact 中的拖放功能返回错误
【发布时间】:2021-03-14 18:58:40
【问题描述】:

我为Drag and Drop files 功能编写了一个程序。
代码:

import React from 'react';
import { Nav, Navbar, Container, Jumbotron } from 'react-bootstrap';
import styled from 'styled-components';

const Styles = styled.div`    
    .navbar { 
        background-color: #fff; 
        border-bottom: 1px solid #4AA69D;
    }
    a, .navbar-nav, .navbar-light .nav-link {
        color: #000;
        &:hover { 
            color: #000; 
        }
    }
    .navbar-brand {
        font-size: 1.4em;
        color: #000;
        display: flex;
        align-items: center;
        text-transform: uppercase;
        letter-spacing: 5px;
        &:hover { 
            color: #000; 
        }
    }
    .imgPos {
        margin-right: 4%;
    }
    .profilediv {
        background: #fff;
        border-radius: 50%;
        border: 1px solid #4AA69D;
        width: 50px;
        height: 50px;
    }
    .dragdropContainer {
        margin-top: 2%;
    }
    .jumbotronSurvey {
        text-align: center;
    }
`;

const Shop = props => {
    // const { data, dispatch } = props;
    const handleDragEnter = e => {
        e.preventDefault();
        e.stopPropagation();
        dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth + 1 });
    };
    const handleDragLeave = e => {
        e.preventDefault();
        e.stopPropagation();
        dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth - 1 });
        if (data.dropDepth > 0) return
        dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false })
    };
    const handleDragOver = e => {
        e.preventDefault();
        e.stopPropagation();
    };
    const handleDrop = e => {
        e.preventDefault();
        e.stopPropagation();
    };
    const reducer = (state, action) => {
        switch (action.type) {
            case 'SET_DROP_DEPTH':
                return { ...state, dropDepth: action.dropDepth }
            case 'SET_IN_DROP_ZONE':
                return { ...state, inDropZone: action.inDropZone };
            case 'ADD_FILE_TO_LIST':
                return { ...state, fileList: state.fileList.concat(action.files) };
            default:
                return state;
        }
    };
    const [data, dispatch] = React.useReducer(
        reducer, { dropDepth: 0, inDropZone: false, fileList: [] }
    )
    return(
        <Styles>
            <Navbar expand="lg">
                <Navbar.Brand href="/">
                <img
                    alt=""
                    src="/image.png"
                    width="30"
                    height="30"
                    className="d-inline-block align-top imgPos"
                    />{' '}
                    SurveyChamp
                </Navbar.Brand>
                <Nav className="ml-auto">
                    <div className="profilediv">
                        <span>
                            {/* ToBeAddedLater */}
                        </span>
                    </div>
                </Nav>
            </Navbar>
            <Container fluid className="dragdropContainer">
                <Jumbotron className="jumbotronSurvey"
                        onDrop={e => handleDrop(e)}
                        onDragOver={e => handleDragOver(e)}
                        onDragEnter={e => handleDragEnter(e)}
                        onDragLeave={e => handleDragLeave(e)}
                        data={data} dispatch={dispatch}
                    >
                    <h5>
                        Drag and drop a JSON file to create a survey
                    </h5>
                </Jumbotron>
            </Container>
        </Styles>
    );
};

export default Shop;  

运行此代码会返回此错误。

标签上的 prop dispatch 值无效。要么将其从元素中移除,要么传递一个字符串或数值以将其保留在 DOM 中。

我已经声明了datadispatch。但是Drag and drop 功能不起作用。我错过了什么?

【问题讨论】:

    标签: reactjs drag-and-drop


    【解决方案1】:

    修好了!!
    我为 DragAndDrop 功能创建了一个组件。这是修改后的代码:
    DragnDrop:

    import React from 'react';
    import { Jumbotron } from 'react-bootstrap';
    
    const DragnDrop = props => { 
        const { data, dispatch } = props;
    
        const handleDragEnter = e => {
            e.preventDefault();
            e.stopPropagation();
    
            dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth + 1 });
        };
    
        const handleDragLeave = e => {
            e.preventDefault();
            e.stopPropagation();
    
            dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth - 1 });
            if (data.dropDepth > 0) return
            dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false })
        };
    
        const handleDragOver = e => {
            e.preventDefault();
            e.stopPropagation();
    
            e.dataTransfer.dropEffect = 'copy';
            dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: true });
        };
    
        const handleDrop = e => {
            e.preventDefault();
            e.stopPropagation();
    
            let files = [...e.dataTransfer.files];
    
            if (files && files.length > 0) {
            const existingFiles = data.fileList.map(f => f.name)
            files = files.filter(f => !existingFiles.includes(f.name))
    
            dispatch({ type: 'ADD_FILE_TO_LIST', files });
            dispatch({ type: 'SET_DROP_DEPTH', dropDepth: 0 });
            dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false });
            }
        };
        return (
            <Jumbotron 
                className={data.inDropZone ? 'drag-drop-zone inside-drag-area' : 'drag-drop-zone'}
                onDrop={e => handleDrop(e)}
                onDragOver={e => handleDragOver(e)}
                onDragEnter={e => handleDragEnter(e)}
                onDragLeave={e => handleDragLeave(e)}
            >
                <h5>Drag json file here to upload</h5>  
            </Jumbotron>
          );
    };
    
    export default DragnDrop;
    

    然后我将它导入到所需的组件中:

    import React from 'react';
    import { Nav, Navbar, Container } from 'react-bootstrap';
    import styled from 'styled-components';
    
    import DragnDrop from '../DragAndDrop/DragnDrop';
    
    const Styles = styled.div`    
        .navbar { 
            background-color: #fff; 
            border-bottom: 1px solid #4AA69D;
        }
        a, .navbar-nav, .navbar-light .nav-link {
            color: #000;
            &:hover { 
                color: #000; 
            }
        }
        .navbar-brand {
            font-size: 1.4em;
            color: #000;
            display: flex;
            align-items: center;
            text-transform: uppercase;
            letter-spacing: 5px;
            &:hover { 
                color: #000; 
            }
        }
        .imgPos {
            margin-right: 4%;
        }
        .profilediv {
            background: #fff;
            border-radius: 50%;
            border: 1px solid #4AA69D;
            width: 50px;
            height: 50px;
        }
        .dragdropContainer {
            margin-top: 2%;
        }
        .jumbotronSurvey {
            text-align: center;
        }
    `;
    
    const NewSurvey = props => {
        const reducer = (state, action) => {
            switch (action.type) {
                case 'SET_DROP_DEPTH':
                return { ...state, dropDepth: action.dropDepth }
                case 'SET_IN_DROP_ZONE':
                return { ...state, inDropZone: action.inDropZone };
                case 'ADD_FILE_TO_LIST':
                return { ...state, fileList: state.fileList.concat(action.files) };
                default:
                return state;
            }
        };
    
        const [data, dispatch] = React.useReducer(
            reducer, { dropDepth: 0, inDropZone: false, fileList: [] }
        )
        return(
            <Styles>
                <Navbar expand="lg">
                    <Navbar.Brand href="/">
                    <img
                        alt=""
                        src="/image.png"
                        width="30"
                        height="30"
                        className="d-inline-block align-top imgPos"
                        />{' '}
                        SurveyChamp
                    </Navbar.Brand>
                    <Nav className="ml-auto">
                        <div className="profilediv">
                            <span>
                                {/* ToBeAddedLater */}
                            </span>
                        </div>
                    </Nav>
                </Navbar>
                <Container fluid className="dragdropContainer">
                    <DragnDrop data={data} dispatch={dispatch} />
                    {/* <ol className="dropped-files">
                        {data.fileList.map(f => {
                            return (
                                <li key={f.name}>{f.name}</li>
                            )
                        })}
                  </ol> */}
                </Container>
            </Styles>
        );
    };
    
    export default NewSurvey;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-22
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      • 2011-11-10
      • 2012-04-14
      相关资源
      最近更新 更多