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=statusreturn 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) returnif(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"><inputclassName="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 onDragEnd={this.onDragEnd}><Droppable droppableId='columns'>{provided=>(<*ref={provided.innerRef}{...provided.droppableProps}// 官方固定格式>自己的代码<*/>{provided.placeholder})}</Droppable>
</DragDropContext>
<Draggable draggableId={String(id)} index={this.props.index}>
{provided=>(<*{...provided.draggableProps}{...provided.dragHandleProps}ref={provided.innerRef}>自己的代码<*/>{provided.placeholder}
)}
</Draggable>
{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}=resultif(!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)}// 点击时渲染不同DOMchoice=(num)=>{this.setState({choice:num})}render() {let uls=nullif(this.state.choice===1){uls=(<DragDropContext onDragEnd={this.onDragEnd}><Droppable droppableId='columns'>{provided=>(<ulref={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=>(<ulref={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=>(<ulref={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 {结构要用的属性或方法的名字} = valuereturn(自己的代码,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} = valueconst completedNum =todos.filter(todo=>todo.completed).lengthconst AllChecked =todos.length?todos.every(todo=>todo.completed):falsereturn(<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实例代办事项相关推荐

  1. 初学者的React全家桶完整实例

    概述 该项目还有些功能在开发过程中,如果您有什么需求,欢迎您与我联系.我希望能够通过这个项目对React初学者,或者Babel/webpack初学者都有一定的帮助.我在此再强调一下,在我写的这些文章末 ...

  2. 【笔记-node】《Egg.js框架入门与实战》、《用 React+React Hook+Egg 造轮子 全栈开发旅游电商应用》

    20210226-20210227:<Egg.js框架入门与实战> 课程地址:https://www.imooc.com/learn/1185 第一章 课程导学 01-01 课程介绍 一. ...

  3. [react] react组件间的通信有哪些?

    [react] react组件间的通信有哪些? Props Context ref:通过Ref获取组建的实例,在通过实例拿到组件的属性值或者方法的回调 第三方的,Redux是基于Conext基础上的库 ...

  4. [react] react与angular、vue有什么区别?

    [react] react与angular.vue有什么区别? Angular以前有接触过,我的感觉是,这不像React和Vue一样是构架+补充库(比如需要另外的全家桶来配合使用),它的功能非常完整, ...

  5. [react] react中的setState执行机制是什么呢?

    [react] react中的setState执行机制是什么呢? 1.将setState传入的partialState参数存储在当前组件实例的state暂存队列中. 2.判断当前React是否处于批量 ...

  6. [react] React.createClass和extends Component的区别有哪些?

    [react] React.createClass和extends Component的区别有哪些? 1.语法 React.createClass和extends采用函数构造 extends Comp ...

  7. 在React / React Native中使用构造函数与getInitialState有什么区别?

    本文翻译自:What is the difference between using constructor vs getInitialState in React / React Native? I ...

  8. golang的GUI库,使用go-fyne设计一个代办事项APP

    Designing task list 我们在这一节中将会设计一个,左边是列表,右边列表中代办事项的具体内容 实现效果如图: 实现该需要使用总共用了两个文件,一个task_list.go packag ...

  9. [react] react中除了在构造函数中绑定this,还有别的方式吗?

    [react] react中除了在构造函数中绑定this,还有别的方式吗? 1:函数定义的时候使用箭头函数 2:函数调用是使用bind绑定this 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放 ...

最新文章

  1. Qt开发,图文详解Hello World全过程
  2. 写代码的16个好习惯,减少80%的bug
  3. dataguard日志传输模式解析_网络运维基础 日志审计
  4. gradle 转 maven
  5. Opencv图像保存到电脑及显示
  6. vs2013 编译libevent32和64bit
  7. 技术人生系列——vCenter重启大法不香了?
  8. 06Matplotlib数据可视化--6.2散点图
  9. Python:将从chrome中复制的cookies转换为字典的函数
  10. python算法常用技巧与内置库
  11. JSP中Cookie在登录功能中的简单应用
  12. 西门子uss通讯实例_西门子USS通信调试经历
  13. C# 利用 OleDb 组件操作 Excel 进行文件读写操作
  14. c# winform 支付宝付款
  15. leetcode报数题
  16. GIS添加图层、查询详细
  17. 瑞萨78K0单片的调试与使用(Minicube2)
  18. paip QQ音乐导出歌单总结
  19. oa系统 云服务器配置,oa系统云服务器配置
  20. Swing制作高仿QQ界面包含主界面、聊天窗口、系统设置窗口|圆角界面|透明|颜色|渲染|换肤

热门文章

  1. 手机蓝牙控制继电器实验
  2. 企业工程管理系统源码-专注项目数字化管理
  3. 计算机毕业设计Java客户关系管理平台(源码+mysql数据库+系统+lw文档)
  4. Just Using Your Imagination.Come On!
  5. 蓝桥杯-算法训练-sign函数
  6. 网易面试题:卡特兰数
  7. 基于element-ui封装下拉表格组件
  8. 爬虫+数据可视化分析
  9. CVE-2020-14750 漏洞复现和Linux打补丁详解
  10. FFTW3在android平台上的移植