前言
在青训营的倒数第二篇笔记
原先的题目:使用React 实现一个简单的待办事项列表:用户可以添加、编辑和删除待办事项;
很菜很菜很菜很菜很菜很菜
准备工作
- Node.js和cnpm(Node.js包管理器)已安装;
- 使用
npm i -g create-react-app全局安装脚手架。
- 使用
npx create-react-app react-todolist创建一个叫react-todolist的项目文件
开始实现 ToDoList
-
将react-todolist导入VS code:
-
将
/src中App.css文件改名为ToDoList.css,App.jsx文件改名为ToDoList.jsx
并且在文件ToDoList.jsx中引入React及useState,将其App方法改名为ToDoList
- 引入注册 ToDoList 组件
在/src中的index.js文件中,将原先注册App的全改为ToDoList:
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import ToDoList from './ToDoList'
import reportWebVitals from './reportWebVitals'
ReactDOM.render(
<React.StrictMode>
<ToDoList />
</React.StrictMode>,
document.getElementById('root')
)
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()
- 创建并渲染列表
在ToDoList函数中创建一个数组 items以及用来更新 items 的函数 Hook -- setItems ,然后声明一个列表渲染函数组件ItemList,使用 map 实现列表的循环:
// 待办事项列表组件
function ItemList(props) {
// 使用map遍历传入数组,返回渲染后的列表
const ItemLists = props.items.map((item, index) => (
// 在 map() 方法中的元素需要设置 key 属性。
<li key={item.id}>
{item.title}
<button>完成</button>
</li>
))
return ItemLists
}
function ToDoList() {
// 初始化待办事项数组
const [items, setItems] = useState([
{
id: 1,
title: '吃饭',
},
{
id: 2,
title: '睡觉',
},
])
return (
<div className="App">
<h1>To Do List</h1>
{/* 待办事项列表 */}
<ul>
{/* 将待办事项数组传入组件 */}
<ItemList items={items}></ItemList>
</ul>
</div>
)
}
export default ToDoList
效果如下:
- 完成后删除事件
添加按钮:
<button onClick={() => clickDelete(index)}>完成</button>
接着在组件ItemList中定义clickDelete事件,因为要更改父元素的items数组,所以我们触发父组件的deleteItem事件
// 点击完成,触发父组件方法
function clickDelete(index) {
props.deleteItem(index)
}
接下来我们给父组件ToDoList绑定删除触发事件deleteItem,目的是被触发时候,将列表中相应的选项删除。
<ItemList deleteItem="{deleteItem}" items="{items}"></ItemList>
最后完成数组items删除事件deleteItem,删除数组中被触发的选项,给数组重新赋值。
// 完成待办
function deleteItem(index) {
items.splice(index, 1)
setItems([...items])
}
- 添加新事项
// 新增代办表单组件
class ItemForm extends React.Component {
constructor(props) {
super(props)
this.state = { value: '' }
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
// 输入框内容更改,更新state
handleChange(event) {
this.setState({ value: event.target.value })
}
// 点击提交按钮,保存选项,请空输入内容
handleSubmit(event) {
event.preventDefault()
if (!this.state.value) {
return
}
this.props.addNewItem(this.state.value)
this.setState({ value: '' })
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
待办事项:
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</label>
<input type="submit" value="提交" />
</form>
)
}
}
然后我们在ToDoList组件引入该组件,并绑定添加事件
{/* 将待办事项数组传入组件,并绑定删除方法 */}
<ItemList deleteItem={deleteItem} items={items}></ItemList>
在 ToDoList组件中,我们声明一个变量id默认为 4。输入框输入内容后,点击添加按钮 数组items 中 push 一条内容,其中包括 id 与 title,然后 id 自增,并且最后更新数组。
// 初始化id
const [itemId, setItemId] = useState(4)
// 初始化待办事项数组
const [items, setItems] = useState([
{
id: 1,
title: '吃饭',
},
{
id: 2,
title: '睡觉',
},
])
// 完成待办
function deleteItem(index) {
items.splice(index,1)
setItems([...items])
}
总结
说实话,这次青训营是我第一次接触前端,在学校学的理论知识好像都是偏向后端的;在青训营跟着老师的视频学的时候还挺懵的,刚开始本次实践的时候也是一脸懵逼,不知道从何下手,后面也是在万能的互联网上找了很多案例来参考学习,最终完成本次实践任务。