react+react-beautiful-dnd实例代办事项_ react-beautiful-dnd教程(1)

自己的代码

)



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 (


待办事项列表


)
}
}

#### 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(



<input
className=“input is-success”
type=“text”
placeholder=“输入代办事项”
value={this.state.inputValue}
onChange={this.handleChang}
onKeyDown={this.handleDown.bind(this)} //该变this指向
ref={this.inputRef}
/>



)
}
}


#### 介绍下[react-beautiful-dnd](https://bbs.csdn.net/topics/618545628)处理函数


* 官方解析图  
 ![请添加图片描述](https://img-blog.csdnimg.cn/401a588ad7f64b2a80cf948255b29292.gif)
* 格式DragDropContext最外面盒子Droppable第二层盒子



{provided=>( <\* ref={provided.innerRef} {...provided.droppableProps} // 官方固定格式 > 自己的代码 <\*/> {provided.placeholder} )}

* 格式Draggable最里面盒子



{provided=>( <\* {...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef} > 自己的代码 <\*/> {provided.placeholder} )}

* 一但移动(从第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){

img
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

is.state.choice===2){

[外链图片转存中…(img-X5gNvUx9-1714709952420)]
[外链图片转存中…(img-A8r4aML6-1714709952421)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
react-beautiful-dnd是一个用于实现拖放功能的React库。它提供了一个优雅的方式来实现复杂的拖放交互,并且在性能方面也表现出色。 官方示例展示了如何在React中使用react-beautiful-dnd来创建一个基本的拖放列表。该示例使用两个列表,左侧列表中有一些颜色方块,右侧列表为空。 首先,我们需要引入所需的库和组件。然后,在页面上创建两个容器,一个用于左侧列表,一个用于右侧列表。接下来,我们需要定义一个状态来存储列表项的数据。在示例中,数据是一个包含颜色方块的数组。我们还需要定义一个函数来处理列表项的拖动和放置操作。 然后,我们可以使用react-beautiful-dnd提供的DragDropContext组件来包裹整个应用,并将其附加到页面的根元素上。这样可以确保拖放操作在整个应用中生效。 接下来,我们需要在左侧列表容器中渲染颜色方块列表,并使用Draggable组件对每个方块进行包装。我们还需要在Draggable组件上设置一个唯一的ID,并使用DragHandleProps和DraggableProps来传递拖动和放置操作的属性。 最后,我们需要在右侧列表容器中渲染一个Droppable组件,以表示可以将颜色方块拖放到其中。并且,我们需要在Droppable组件上使用DroppableProps来传递拖放操作的属性。 通过以上步骤,我们就可以创建一个简单的拖放列表。当我们拖动一个颜色方块时,react-beautiful-dnd会自动处理其它方块的重新排序和位置更新。同时,我们还可以添加一些自定义的逻辑来实现更复杂的拖放交互效果。 总之,react-beautiful-dnd官方示例展示了如何使用这个库来创建一个基本的拖放列表。通过这个示例,我们可以学习到如何在React中使用react-beautiful-dnd,并了解其强大的拖放功能和灵活的配置选项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值