react react-beautiful-dnd应用

效果预览

请添加图片描述

实现思路

index.js入口文件配置

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import 'bulma-start/css/main.css' // 引入bulma样式
ReactDOM.render(
  <App/>,
  document.getElementById('root')
)

app.jsx主页面配置

Provider格式

return(
<Provider value={{
	'要在tree传递的名字':this.'具体属性或方法'
}}>
自己的代码
</Provider>
)
import React,{ Component} from "react";
import TodoHeader from './components/TodoHeader.jsx'
import TodoInput from "./components/TodoInput";
import TodoList from "./components/TodoList";
import TodoFoot from "./components/TodoFoot";
import {Provider} from "./untils/with-context" // 引入TodoContext组件
export default class App extends Component{
    state ={
        todos:Array(6).fill(null).map((_,index)=>({
            id:index  ,
            title:'待办事项' index  ,
            completed: Math.random()>0.5,
        }))
    }
    // 拖拽后的更新state处理函数
    drag(newTodos){
        this.setState({
            todos:[...newTodos],
        })

    }
    // 添加事件处理函数
    addTodoItem=title=>{
        this.setState({
            todos:[
                ...this.state.todos,
                {
                    /* id:this.state.todos[this.state.todos.length-1] 1,
                    *	更新setState是异步的,这里是拿不到最新的state
                    */
                    id:Math.random(),
                    title,
                    completed:false,
                }
            ]
        })

    }
    // 删除事件处理函数
    delTodo=id=>{
        this.setState({
            todos:this.state.todos.filter(todo=>todo.id !==id)
        })
    }
    // 更改事件状态处理函数
    changComple=id=>{
        this.setState({
            todos:this.state.todos.map(todo=>{
                if(todo.id === id){
                    todo.completed=!todo.completed
                }
                return todo
            })
        })

    }
    // 根据总选框状态设置每个单选框状态
    allCheckbox=(status)=>{
        this.setState({
            todos:this.state.todos.map(todo=>{
                todo.completed=status
                return todo
            })
        })
    }
    // 删除已完成事件
    delCompelted=()=>{
        this.setState({
            todos:this.state.todos.filter(todo=>!todo.completed)
        })
    }
    render() {
        return(
            <Provider value={{
                todos:this.state.todos,
                changComple:this.changComple,
                delTodo:this.delTodo,
                allCheckbox:this.allCheckbox,
                delCompelted:this.delCompelted,
            }}>
                <article className="panel is-success">
                    <TodoHeader/>
                    <TodoInput add={this.addTodoItem}/>
                    <TodoList todos={this.state.todos} drag={this.drag.bind(this)}/>
                    <TodoFoot/>

                </article>
            </Provider>

        )
    }
}

untils/with-context.js封装工具todoContext

import {createContext} from "react";
// 创建creatContext对象
const TodoContext = createContext()
// 结构要用到的React组件
const {
    Provider, // 生产组件
    Consumer, // 消费组件
} = TodoContext
export {
    Provider,
    Consumer,
    TodoContext,
}

components/TodoHeader.jsx页面头部

import React, { Component } from 'react'
export default class TodoHeader extends Component {
    render() {
        return (
            <p className="panel-heading">
                待办事项列表
            </p>
        )
    }
}

components/TodoInput.jsx该文件主要负责添加事件

import React, {Component, createRef} from "react";
export default class TodoInput extends Component{
    state={
        inputValue:'输入代办事件', // 定义input输入框内容
    }
    inputRef=createRef() // 定义ref绑定DOM元素,作用是为下面自动获取焦点做准备
    // 输入框中输入的内容设置给state作用1:输入框内容改变2:后面提交添加事件拿到input内容
    handleChang=Event=>{
        this.setState({
            inputValue:Event.target.value
        })
    }
    // 添加代办事件
    handleDown=Event=>{
        // 验证下是否为空
        if(this.state.inputValue==='' || this.state.inputValue===null) return
        if(Event.keyCode ===13){
            this.add()
        }
    }
    // 添加处理函数
    add=()=>{
        // add方法通过props从App传入
        this.props.add(this.state.inputValue)
        this.state.inputValue=''
        // ref绑定后通过inputRef.current拿到DOM元素
        this.inputRef.current.focus()
    }
    render() {
        return(
                <div className="panel-block">
                    <p className="control has-icons-left">
                        <input
                            className="input is-success"
                            type="text"
                            placeholder="输入代办事项"
                            value={this.state.inputValue}
                            onChange={this.handleChang}
                            onKeyDown={this.handleDown.bind(this)} //该变this指向
                            ref={this.inputRef}
                        />
                    </p>
                </div>
        )
    }
}

介绍下react-beautiful-dnd处理函数

官方解析图

请添加图片描述

格式DragDropContext最外面盒子Droppable第二层盒子

<DragDropContext onDragEnd={this.onDragEnd}>
	<Droppable droppableId='columns'>
		{provided=>(
		<*
			 ref={provided.innerRef}
             {...provided.droppableProps}
             // 官方固定格式
		>
		自己的代码
		<*/>
		{provided.placeholder}
		)}
	</Droppable>
</DragDropContext>

格式Draggable最里面盒子

<Draggable draggableId={String(id)} index={this.props.index}>
{provided=>(
	<*
	 {...provided.draggableProps}
     {...provided.dragHandleProps}
     ref={provided.innerRef}
	>
	自己的代码
	<*/>
	{provided.placeholder}
)}
</Draggable>

一但移动(从第5个事件移动到第4个事件)onDragEnd回调函数打印结果console.log(result)

{draggableId: '5', type: 'DEFAULT', source: {…}, reason: 'DROP', mode: 'FLUID', …}
combine: null
destination: {droppableId: 'columns', index: 4} // 移动到第4个事件
draggableId: "5"
mode: "FLUID"
reason: "DROP"
source: {index: 5, droppableId: 'columns'} // 移动的第5个事件
type: "DEFAULT"
[[Prototype]]: Object

components/TodoList.jsx

import React,{Component} from "react";
import TodoItem from "./TodoItem";
import PropTypes from 'prop-types'
import {DragDropContext} from 'react-beautiful-dnd'
import {Droppable} from 'react-beautiful-dnd'
export default class TodoList extends Component{
    // 类型检查
    static propTypes={
        todos:PropTypes.array.isRequired,
    }
    // 默认值
    static defaultProps = {
        todos: [],
    }
    // 根据choice数值决定渲染事项
    state={
        choice:1
    }
    // react-beautiful-dnd核心处理函数,负责交换后的处理(可以自定义)
    onDragEnd=result=>{
        console.log(result)
        const {destination,source,draggableId}=result
        if(!destination){ // 移动到了视图之外
            return
        }
        if( // 移动到原来位置,也就是位置不变
            destination.droppableId===source.droppableId &&
            destination.index===source.index
        ){ return;}
        const newTaskIds=Array.from(this.props.todos) // 转化为真正的数组
        newTaskIds.splice(source.index,1) // 删除移动的数组
        newTaskIds.splice(destination.index,0,this.props.todos[source.index]) // 在移动到的位置初放置被删除的数组
        // 调用App文件中的drag执行交换后的更改
        this.props.drag(newTaskIds)
    }
    // 点击时渲染不同DOM
    choice=(num)=>{
        this.setState({
            choice:num
        })
    }
    render() {
        let uls=null
        if(this.state.choice===1){
            uls=(<DragDropContext onDragEnd={this.onDragEnd}>
                    <Droppable droppableId='columns'>
                        {provided=>(
                            <ul
                                ref={provided.innerRef}
                                {...provided.droppableProps}
                            >
                                {this.props.todos.length>0
                                    ? this.props.todos.map((todo,index)=>{
                                        return (
                                            <TodoItem key={todo.id} todo={todo} index={index}/>
                                        )
                                    })
                                    :<div>添加代办事项</div>
                                }
                                {provided.placeholder}
                            </ul>
                        )}
                    </Droppable>
                </DragDropContext>)
        }else if(this.state.choice===2){
            // 过滤下事件
            let newtodos=this.props.todos.filter(todo=> todo.completed)
                uls=(<DragDropContext onDragEnd={this.onDragEnd}>
                    <Droppable droppableId='columns'>
                        {provided=>(
                            <ul
                                ref={provided.innerRef}
                                {...provided.droppableProps}
                            >
                                {newtodos.length>0
                                    ? newtodos.map((todo,index)=>{
                                        return (
                                            <TodoItem key={todo.id} todo={todo} index={index}/>
                                        )
                                    })
                                    :<div>暂无已完成事件</div>
                                }
                                {provided.placeholder}
                            </ul>
                        )}
                    </Droppable>
                </DragDropContext>)
        }else if(this.state.choice===3){
            // 过滤下事件
            let newtodos=this.props.todos.filter(todo=> !todo.completed)
            uls=(<DragDropContext onDragEnd={this.onDragEnd}>
                <Droppable droppableId='columns'>
                    {provided=>(
                        <ul
                            ref={provided.innerRef}
                            {...provided.droppableProps}
                        >
                            {newtodos.length>0
                                ? newtodos.map((todo,index)=>{
                                    return (
                                        <TodoItem key={todo.id} todo={todo} index={index}/>
                                    )
                                })
                                :<div>暂无未完成事件</div>
                            }
                            {provided.placeholder}
                        </ul>
                    )}
                </Droppable>
            </DragDropContext>)
        }
        return(
            <>
                   <p className="panel-tabs">
                         <a className="is-active" onClick={()=>this.choice(1)}>所有</a>
                         <a onClick={()=>this.choice(2)}>已完成</a>
                         <a onClick={()=>this.choice(3)}>未完成</a>
                    </p>
                  {uls}
            </>
        )
    }
}

components/TodoFoot.jsx Consumer格式

return(
	 <Consumer>
	 {value=>{
	 const {结构要用的属性或方法的名字} = value
	 return(
	 	 自己的代码,value中含有Provider中传入的所有值
	 )
	 }}
	 </Consumer>
)
import React,{Component} from "react";
import {Consumer} from '../untils/with-context'
export default class TodoFoot extends Component{
    render() {
        return(
            <Consumer>
                {
                    value => {
                        const {allCheckbox,todos,delCompelted} = value
                        const completedNum =todos.filter(todo=>todo.completed).length
                        const AllChecked =todos.length?todos.every(todo=>todo.completed):false
                        return(
                            <div>
                                <label className="panel-block">
                                    <input type="checkbox" checked={AllChecked} onChange={(event)=>allCheckbox(event.target.checked)}/>全选
                                    <span>已完成{completedNum}</span>
                                    <span>一共{todos.length}</span>
                                </label>
                                <div className="panel-block">
                                    <button className="button is-success is-outlined is-fullwidth" onClick={delCompelted}>
                                        删除已完成
                                    </button>
                                </div>
                            </div>
                        )
                    }
                }
            </Consumer>

        )
    }
}

package.json中的三方包资源

{
  "name": "react-demo",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "bulma-start": "^0.0.5",
    "react": "^17.0.2",
    "react-beautiful-dnd": "^13.1.0",
    "react-dom": "^17.0.2",
    "react-native": "^0.68.2",
    "react-scripts": "4.0.3",
    "redux-persist": "^6.0.0",
    "store": "^2.0.12",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

到此这篇关于react react-beautiful-dnd实例代办事项的文章就介绍到这了,更多相关react代办事项内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

react+react-beautiful-dnd实现代办事项思路详解的更多相关文章

  1. ios – React native链接到另一个应用程序

    如果是错误的,有人知道如何调用正确的吗?

  2. ios – React Native – 在异步操作后导航

    我正在使用ReactNative和Redux开发移动应用程序,我正面临着软件设计问题.我想调用RESTAPI进行登录,如果该操作成功,则导航到主视图.我正在使用redux和thunk所以我已经实现了异步操作,所以我的主要疑问是:我应该把逻辑导航到主视图?我可以直接从动作访问导航器对象并在那里执行导航吗?.我对组件中的逻辑没有信心.似乎不是一个好习惯.有没有其他方法可以做到这一点?

  3. 在ios中使用带有React Native(0.43.4)的cocoapods的正确方法是什么?

    我已经挖掘了很多帖子试图使用cocoapods为本地ios库设置一个反应原生项目,但我不可避免地在#import中找到了丢失文件的错误.我的AppDelegate.m文件中的语句.什么是使用反应原生的可可豆荚的正确方法?在这篇文章发表时,我目前的RN版本是0.43.4,而我正在使用Xcode8.2.1.这是我的过程,好奇我可能会出错:1)

  4. ios – React Native WebView滚动行为无法按预期工作

    如何确保滚动事件的行为与ReactNative应用程序中的浏览器相同?

  5. ios – React Native – BVLinearGradient – 找不到’React/RCTViewManager.h’文件

    谢谢.解决方法几天前我遇到了完全相同的问题.问题是在构建应用程序时React尚未链接.试试这个:转到Product=>Scheme=>管理方案…=>点击你的应用程序Scheme,然后点击Edit=>转到Build选项卡=>取消选中ParallelizeBuild然后点击标志添加目标=>搜索React,选择第一个名为React的目标,然后单击Add然后在目标列表中选择React并将其向上拖动到该列表中的第一个.然后转到Product=>再次清理并构建项目.这应该有所帮助.

  6. ios – React Native – NSNumber无法转换为NSString

    解决方法在你的fontWeight()函数中也许变成:

  7. ios – React native error – react-native-xcode.sh:line 45:react-native:command not found命令/ bin/sh失败,退出代码127

    尝试构建任何(新的或旧的)项目时出现此错误.我的节点是版本4.2.1,react-native是版本0.1.7.我看过其他有相同问题的人,所以我已经更新了本机的最新版本,但是我仍然无法通过xcode构建任何项目.解决方法要解决此问题,请使用以下步骤:>使用节点版本v4.2.1>cd进入[你的应用]/node_modules/react-native/packager>$sh./packager.s

  8. 反应原生 – 如何通过Xcode构建React Native iOS应用程序到设备?

    我试图将AwesomeProject应用程序构建到设备上.构建成功并启动屏幕显示,但后来我看到一个红色的“无法连接到开发服务器”屏幕.它表示“确保节点服务器正在运行–从Reactroot运行”npmstart“.看起来节点服务器已经运行,因为当我做npm启动时,我收到一个EADDRINUSE消息,表示该端口已经在使用.解决方法从设备访问开发服务器您可以使用开发服务器快速迭代设备.要做到这一点,你的

  9. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  10. 如何为iOS的React Native设置分析

    所以我已经完成了一个针对iOS的ReactNative项目,但是我想在其中分析.我尝试了react-native-google-analytics软件包,但是问题阻止了它的正常工作.此外,react-native-cordova-plugin软件包只适用于Android,因此插入Cordova插件进行分析的能力现在已成为问题.我也没有Swift/ObjectiveC的经验,所以将完全失去GA的插入.有没有人有任何建议如何连接GoogleAnalytics的ReactNativeforiOS?

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部