反应待办事项列表
介绍
本指南分为两部分,将使用 React 开发一个简单的待办事项列表。我们将首先学习如何显示列表、添加将项目标记为已完成的功能,最后学习如何按已完成和逾期项目筛选列表。
第二部分,我们将探索如何使用模拟 API 来检索和更新列表,以及添加函数来添加新项目,从而使我们的列表更加动态。
本指南需要包含hooks API的 React 版本,并假定Bootstrap可用。此文件将提供额外的 CSS 。
应用程序将从页面顶部的标题组件开始。标题组件首先显示应用程序的标题,如下所示:
function Header() {
return (
<header>
<nav className="navbar navbar-light bg-light">
<span className="navbar-brand">
Todo list
</span>
</nav>
</header>);
}
列出项目
待办事项列表需要做的第一件事是视图中的待办事项列表。首先,将在一个 json 文件中定义如下:
{
"Items": [
{
"id": "1",
"timestampDue": 1561881986756,
"name": "Pay credit card bill",
"complete": false
}
...
]
}
数据包含一个唯一的 ID、待办事项到期日期/时间的时间戳、事项名称以及用于确定是否已完成的布尔值。此文件可以像这样导入到应用程序中:
import todo from "./mockData.json";
为了在视图中显示项目,可以使用以下代码:
<ul className="list-group">
{todo.Items.map(item => (
<li key={item.id} className="list-group-item">
{`${item.name} - ${dateformat(new Date(item.timestampDue), "dd-mmm-yyyy")}`}
</li>))}
</ul>
这将创建一个ul元素,并将列表中的每个项目映射到一个li元素,该元素仅包含待办事项的名称以及项目的截止日期。日期使用dateformat 包进行格式化。请注意在li上设置的key属性;当从列表中渲染多个组件时,React 需要每个组件都有一个唯一的 key 属性,以确定列表及其中的任何项目何时发生了变化。
虽然这段代码很好,但我们应该使用组件组合的原理,特别是考虑到我们知道很快就会向列表中的某项添加额外的功能。为此,可以将li元素提取到接受该项作为 prop 的新组件中。操作如下:
function Item({ item }) {
return (
<li className="list-group-item">
{`${item.name} - ${dateformat(new Date(item.timestampDue), "dd-mmm-yyyy")}`}
</li>);
}
此函数组件接受item作为 prop。函数参数列表{ item }中的语法使用对象解构来提取每个 prop;该函数可以接受像这样的参数(props)并像props.item一样引用该项目。
这个新组件可以像这样使用:
{todo.Items.map(item => <Item key={item.id} item={item} />)}
这里所做的就是,不是将每个项目直接映射到li元素,而是将每个项目映射到Item组件。请注意,key 属性现在设置在Item组件上。
此 UI 中可能有用的一项功能是突出显示已过期的任何项目。要计算项目是否过期,只需获取项目的timestampDue属性并检查它是否早于当前时间戳;对于任何已完成的项目,它也不应返回 true。
此功能将计算某项是否逾期:
function isOverdue(item) {
return !item.complete && item.timestampDue < new Date().getTime();
}
然后可以使用它来将li元素的类设置为list-group-item list-group-item-danger(如果逾期),否则设置为list-group-item list-group-item-info ,如下所示:
const itemClass = `list-group-item list-group-item-${isOverdue(item) ? "danger" : "info"}`;
return (
<li className={itemClass}>
...
</li>);
待办事项应用程序现在有一个待办事项列表,并区分逾期事项和未逾期事项。
完整商品
一旦列表中的项目已完成,就需要将其设置为完成,以便可以显示为完成,或者在指南的后面根本不显示。
目前,待办事项是从 json 文件导入的,并由代码直接访问;当我们要开始更改列表中的项目时,它们需要存储在组件状态中。具体做法如下:
const [items, setItems] = React.useState(todo.Items);
function completeItem(id) {
const updatedItems = items.map(item =>
(item.id === id ? { ...item, complete: true } : item));
setItems(updatedItems);
}
此函数使用map 数组函数来投射新的列表项。如果项的 ID 与正在设置的项的 ID 不匹配,则map将返回相同的项;如果项与 ID 匹配,则使用对象展开运算符返回一个新项,该项具有所有相同的属性,但complete设置为 true。然后,将此新列表传递给setItems,并更新相关组件。
剩下的就是允许用户将一个项目设置为完成,并在 UI 中将一个项目显示为完成;这两个更改都将在Item组件中进行。
首先,组件需要添加一个按钮,供用户单击以完成项目,然后接受新的completeItem属性,该属性将是单击按钮时要调用的函数,最终将使用项目的 ID 调用completeItem函数。最后,可以向项目的文本添加一个类,以便可以将其显示为已完成 - 在本指南中使用的示例 CSS 中,已完成的项目将显示为划掉的略微不透明的。
最终的Item组件如下所示:
function Item({ item, completeItem }) {
const itemClass = `list-group-item list-group-item-${isOverdue(item) ? "danger" : "info"}`;
return (
<li className={itemClass}>
<div className="item">
<span className={`item-title${item.complete ? " complete-item" : ""}`}>
{`${item.name} - ${dateformat(new Date(item.timestampDue), "dd-mmm-yyyy")}`}
</span>
{!item.complete && (
<button type="button" className="btn btn-link" onClick={completeItem}>
Complete item
</button>)}
</div>
</li>);
}
li内的新div只是为了确保按钮显示在组件的右侧,span用于显示文本是否完成,并且仅当项目尚未完成时才会呈现按钮。
此组件的用法也需要更改 - 现在需要一个completeItem属性。项目列表现在构建如下:
{items.map(item => (
<Item key={item.id} item={item} completeItem={() => completeItem(item.id)} />))}
completeItem prop 被设置为一个箭头函数,该函数将当前item.id传递给completeItem函数。
过滤列表
应用程序中要添加的最后一项功能是列表过滤。目前,列表中的所有项目都会显示,无论其完成状态如何,这意味着一段时间后,用户可能很难发现未完成的项目。除非用户明确要求,否则应用程序不应显示已完成的项目,还应允许用户选择仅显示逾期项目。
这些过滤器需要存储在组件状态中,并通过Header组件中的 UI 进行设置。过滤器状态将像这样初始化:
const [filter, setFilter] =
React.useState({ overdueOnly: false, includeComplete: false<
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~