入门React——实战Todos代办记事本(单向数据流)(四)
目录
单向数据流
在我们的实战讲解之前我们要清楚单项数据流的概念,虽然我们在前面的文章中已经提及过这个只是,但是我们还是徐娅强调这个,因为单项数据流是react数据通信最重要的概念。React采用单项数据流模型,意味着数据在一个组件树中从上至下单向传递,不鼓励反向或者多向的数据传播。
react遵循:数据生成页面
的宗旨,React应用的核心思想是“UI = f(data)”(用户界面是数据的函数)。这意味着React组件根据其接收的数据(props
和内部state
)来决定如何渲染。当数据变化时,React通过虚拟DOM高效地计算出最小化的DOM更新,从而实现页面的动态更新。计算虚拟DOM最小化的DOM更新就是通过React组件的render
方法负责根据当前的props
和state
生成虚拟DOM树。React比较前后虚拟DOM差异,仅对实际DOM做出必要的最小更新。
准备文件
开始工作前准备好4个文件,并实现基本配置,每个jsx文件内配置继承好commponent
对象
import './addList.css' //引入css
import {Component} from 'react'
class AddList extends Component{
constructor(props){
super(props)
this.state = {
}
}
}
}
render(){
return()
}
}
export default AddList //导出函数
App.jsx文件配置
我们将数据都存贮在父组件中,由于单项数据流的原则,接下来的增删改操作函数我们也将全部在App.jsx文件中完成,然后传递给子组件。
设置默认数据给state
配置render()内的JSX
addTodos
添加代办操作handleDelete
删除代办操作handleComplete
完成代办操作
addTodos
添加代办操作
addTodos=(text)=>{
this.setState({
todos:[
...this.state.todos,
{
title:text,
completed: false
}
]
})
}
为什么要...this.state.todos
再在后面进行添加操作,而不是直接使用
this.state.todos.push({title:text,completed: false})
?
因为:直接修改原状态违反了React状态应该是不可变的原则。修改原数组不会触发React组件的重新渲染,因为React通过比较引用(reference)而非内容来判断是否需要更新,直接修改数组不会改变其引用。
handleDelete
删除代办操作
handleDelete=(index)=>{
this.setState({
todos: this.state.todos.filter((todo, i) => index !== i)
})
}
这里我们使用filter
方法来剔除删除传入的下标值来操作原数组,注意这里是符合单向数据流原则的,因为filter
是返回一个新数组,因此这时候的state的引用时发生改变的。
handleComplete
完成代办操作
handleComplete=(index)=>{
this.setState({
todos: this.state.todos.map((todo, i) =>
i === index? {...todo, completed:!todo.completed} : todo
)
})
}
与filter
方法相似,map
方法也会遍历所有数据并返回一个新数组,但是map是不论判断值为真假都会将它返回,因此我们可以直接使用三目运算符,如果是目标下标,则将complete
值进行修改再返回 {...todo, completed:!todo.completed}
使用!todo.completed
方便将complete
实现true
orfalse
addList.jsx文件配置
我们在addList.jsx
文件中使用表单form
来控制提交,因为使用表单提交提升了用户体验和可访问性,还简化了数据收集和处理的逻辑,提高了开发效率,我们在开发中遇到这种提交输入框数据应该尽量使用表单来设计。
handleChange()监视输入框
//修改状态
handleChange=(event)=>{
this.setState({
inputText: event.target.value
})
}
在input框中我们将框内数据value绑定与 value={this.state.inputText}
,但这还不够,这时候只实现了value
与this.state.inputText
单项数据绑定,value只是在初始化的值会等于this.state.inputText
而实现双向绑定需要在设定一个handleChange
函数
handleAdd()提交函数
handleAdd = (e) => {
e.preventDefault() //阻止默认跳转行为
if(this.state.inputText.trim()){
this.props.addTodos(this.state.inputText)
this.setState({
inputText: ''
})
}
}
在我们输入完成将要添加数据前我们也需要通过handleAdd
函数来先进行输入框的判断,输入框的内容是否在去除首尾空白后仍非空。若非空则提提交成功,清除input中的value
listContent文件配置
这里在ul
内调用renderList
函数将返回值进行渲染。
这里我们使用map遍历直接对于todos
数组遍历的每一个item
,创建一个<li>
列表项元素。每个li
元素都有一个唯一的key
属性,使用数组索引index
作为key
,并给li
内的buttom
添加上绑定事件handleDelete
,handleComplete
总结
-
组件结构:在开始实现一个项目前,我们应该先确定好项目结构,并将项目进行组件划分。这个应用由三个主要部分组成:
App
组件:作为整个应用的根组件,管理状态(state)并协调子组件。AddList
组件:负责接收用户输入并添加新的待办事项到列表。ListContent
组件:负责展示待办事项列表,以及提供删除和修改完成状态的功能。
-
状态管理:在组件中,使用
constructor
初始化状态state
来存储需要响应式数据,其中包含一个todos
数组,用于存储所有待办事项的信息(包括标题和完成状态)。 -
添加待办事项:在App.jsx文件中实现
addTodos
方法并传给在AddList
组件,当用户在AddList
组件中提交新事项时会调用到addTodos
方法,将新事项追加到todos
数组中,同时设置其初始完成状态为false
。 -
删除待办事项:与添加待办事项一样,
handleDelete
方法也是实现在在App.jsx文件中,被listContent.jsx文件调用。根据传入的索引index
,从todos
数组中过滤掉对应项,从而实现删除功能。 -
切换完成状态:
handleComplete
方法利用map
返回值遍历todos
数组,因为react中没有类似v-for的强制化指令,更加体现页面即数据的理念。
感谢阅读!
转载自:https://juejin.cn/post/7387303384082841627