react基础学习 附加todo实现代码

简介

学习目的

我们在学习GUI开发的时候一般思考两个问题

  1. 如何来设计UI?
  2. 如何实现前后端数据交互?

问题一

React引入了tsx语法,让我们能够在ts中自由的嵌入html,让我们能只写tsx代码,来实现UI的控制,而不是把所有的UI都放进一个html文件中,让各个部分更好维护

所react中,我们使用组件来表示各个小的部分

那与之而来的问题,react是如何将tsx代码变成网页的呢?

要知道,我们使用react可以不写任何html实现网页效果

答案是使用虚拟dom,即由react管理的dom,我们的tsx语法都会先映射到这个虚拟的dom上,然后react来对比改变的部分,然后render到浏览器中的dom上,这样还能减少对浏览器dom的更改,节省了性能

问题二

我们的数据通过hook来修改,根据不同需要,可以封装不同的修改


React(React.js或ReactJS)是由Facebook开发并维护的一款用于构建用户界面的JavaScript库。React主要用于构建单页面应用程序(Single Page Applications)中的用户界面,通过组件化开发的方式,可以更轻松地构建和维护复杂的前端应用。

React的设计目标是提高前端开发的效率和可维护性,使得开发者能够更容易地构建现代、响应式的用户界面。它广泛应用于各种Web应用开发项目,并且与其他技术(如React Native)结合,使得开发者可以用相似的方式构建Web、移动端等不同平台上的应用。

运行环境

1. 创建 React 应用

在工作目录下打开终端,输入下面命令,设置名称为my-app后全部yes

npx create-next-app@latest

2. 进入 create-react-app 创建的文件夹并安装 typescript

cd my-app

3.启动 React

npm run dev

然后会自动在浏览器打开localhost:3000网页,然后就能看到官方示例了

HOOK

格式如下,解释 : 用setTodos来设置todos,并初始值为<Todo[]>([])这个空列表

  const [todos, setTodos] = useState<Todo[]>([])

然后我们可以利用这个来管理todos,如下

  const addTodo = (text: string) => {const newTodo = {id: Date.now(),text,completed: false}setTodos([...todos, newTodo])//打开旧的,添加新的}const deleteTodo = (id: number) => {setTodos(todos.filter(todo => todo.id !== id))//将不需要删除的筛选出来称为新的}const toggleTodo = (id: number) => {setTodos(todos.map(todo => {if (todo.id === id) {todo.completed = !todo.completed}return todo}))}

TSX

TSX是TypeScript代码中嵌套XML标记的语法扩展。方便描述用户界面的结构。

所以跟其他ts类型的使用方法相同,可以类比字符串理解

常见用法

声明

const element = <h1>Hello, world!</h1>;

格式化

const name = "Josh Perez";
const element = <h1>Hello, {name}</h1>;ReactDOM.render(element, document.getElementById("root"));

返回值

function getGreeting(user) {if (user) {return <h1>Hello, {formatName(user)}!</h1>;}return <h1>Hello, Stranger.</h1>;
}

属性

你可以通过使用引号,来将属性值指定为字符串字面量:

const element = <div tabIndex="0"></div>;

也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:

const element = <img src={user.avatarUrl}></img>;

习惯

在属性中嵌入 JavaScript 表达式时,不要在大括号外面加上引号。你应该仅使用引号(对于字符串值)或大括号(对于表达式)中的一个,对于同一属性不能同时使用这两种符号。

因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。

例如,JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex

原理

babel会把 JSX 转译成一个名为 React.createElement() 函数调用。

以下两种示例代码完全等效:

const element = <h1 className="greeting">Hello, world!</h1>;
const element = React.createElement("h1",{ className: "greeting" },"Hello, world!"
);

React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:

const element = {type: "h1",props: {className: "greeting",children: "Hello, world!",},
};

这些对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。

render

渲染新元素

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById("root"));

更新元素

React 元素是不可变对象。更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()

考虑一个计时器的例子:

function tick() {const element = (<div><h1>Hello, world!</h1><h2>It is {new Date().toLocaleTimeString()}.</h2></div>);ReactDOM.render(element, document.getElementById("root"));
}setInterval(tick, 1000);

这个例子会在 setInterval()回调函数,每秒都调用 ReactDOM.render()。也就是说,它每秒都渲染一个新的 React 元素,并将其传入ReactDOM.render()中。

组件

组件

实际上是函数,props接收任意入参.不过一般参数还是都写好了,便于我们调用

在使用时我们可以像一般html一样使用,不过参数必须要传递

function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}

像用html一样使用,如下

function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}const element = <Welcome name="Sara" />;
ReactDOM.render(element, document.getElementById("root"));

注意: 组件名称必须以大写字母开头

React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签

<Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome

使用

如下将接收的参数的类型可以通过接口AddTodoProps来解释,然后后面就是具体用法了

AddTodo.tsx

import { useState } from "react";interface AddTodoProps {addTodo: (text: string) => void
}function AddTodo({ addTodo }: AddTodoProps) {const [text, setText] = useState('')const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {e.preventDefault();if (text.trim().length === 0) {return}addTodo(text)setText('')}return (<form onSubmit={handleSubmit}><inputtype="text"value={text}onChange={e => setText(e.target.value)}/><button>Add</button></form>)
}export default AddTodo;

page.tsx

像使用一般html标签一样使用,注意传递参数

<AddTodo addTodo={addTodo}></AddTodo>

todo所有代码

pages.tsx

"use client"
import AddTodo from "./components/AddTodo"
import TodoList from "./components/TodoList"
import TodoFilter from "./components/TodoFilter"
import { useState } from "react"
import { Todo } from "./types"export default function Home() {const [todos, setTodos] = useState<Todo[]>([])//在光标处按ctrl可以查看函数原型const [filter, setFilter] = useState('all')const addTodo = (text: string) => {const newTodo = {id: Date.now(),text,completed: false}setTodos([...todos, newTodo])//打开旧的,添加新的}const deleteTodo = (id: number) => {setTodos(todos.filter(todo => todo.id !== id))//将不需要删除的筛选出来称为新的}const toggleTodo = (id: number) => {setTodos(todos.map(todo => {if (todo.id === id) {todo.completed = !todo.completed}return todo}))}const getFilteredTodos = () => {switch (filter) {case 'active':return todos.filter(todo => !todo.completed)case 'completed':return todos.filter(todo => todo.completed)default:return todos;}}return (<div><h1>Todo List</h1><AddTodo addTodo={addTodo}></AddTodo><TodoList todos={getFilteredTodos()} deleteTodo={deleteTodo} toggleTodo={toggleTodo} /><TodoFilter setFilter={setFilter} ></TodoFilter></div>)
}

types.ts

export interface Todo {id: number;text: string;completed: boolean;
}

components

AddTodo.tsx

import { useState } from "react";interface AddTodoProps {addTodo: (text: string) => void
}function AddTodo({ addTodo }: AddTodoProps) {const [text, setText] = useState('')const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {e.preventDefault();if (text.trim().length === 0) {return}addTodo(text)setText('')}return (<form onSubmit={handleSubmit}><inputtype="text"value={text}onChange={e => setText(e.target.value)}/><button>Add</button></form>)
}export default AddTodo;

TodoFilter.tsx

function TodoFilter({ setFilter }: any) {return (<div><button onClick={() => setFilter('all')}>All</button><button onClick={() => setFilter('active')}>Active</button><button onClick={() => setFilter('completed')}>Completed</button></div>)
}export default TodoFilter;

TodoItem.tsx

interface TodoListProps {todo: any;toggleTodo: (id: number) => void;deleteTodo: (id: number) => void;
}function TodoItem({ todo, toggleTodo, deleteTodo }: TodoListProps) {return (<li style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>{todo.text}<button onClick={() => toggleTodo(todo.id)}>切换</button><button onClick={() => deleteTodo(todo.id)}>删除</button></li>)
}
export default TodoItem;

TodoList.tsx

import { Todo } from "../types";
import TodoItem from "./TodoItem";interface TodoListProps {todos: Array<Todo>;toggleTodo: (id: number) => void;deleteTodo: (id: number) => void;
}function TodoList({ todos, toggleTodo, deleteTodo }: TodoListProps) {return (<ul>{todos.map(todo => (<TodoItem key={todo.id} todo={todo} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />))}</ul>)
}export default TodoList;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes 中整合 Istio 的全面指南

大家好&#xff0c;我是升仔 Istio 在 Kubernetes 的关键应用场景 服务间通信的精细控制&#xff1a;Istio 提供路由规则、重试、故障转移和断路器等功能&#xff0c;用于控制和优化服务间的通信。安全性强化&#xff1a;提供了强大的服务间认证和授权功能&#xff0c;确保只…

harmonyOS Column组件通过space属性设置内部元素间距

例如 我们代码如下 import router from ohos.router Entry Component struct Index {build() {Row() {Column() {Text("年后")Text("一起")Text("旅游")}.width(100%)}.height(100%)} }运行之后 元素都粘连到一起 显然不太好看 我们就可以通过…

PM大逃亡

欢迎来到程序小院 PM大逃亡 玩法&#xff1a;点击白色的小鬼&#xff0c;滑动鼠标移动&#xff0c;不要碰到黑色的怪物&#xff0c; 怪物会越来越多&#xff0c;看看你能坚持多久&#xff0c;快去大逃亡吧^^。开始游戏https://www.ormcc.com/play/gameStart/233 html <div…

分享Python采集40个NET整站程序源码,总有一款适合您

分享Python采集40个NET整站程序源码&#xff0c;总有一款适合您 Python采集的40个NET整站程序源码下载链接&#xff1a;https://pan.baidu.com/s/1z54JHJkFYa4Kx2oBtPrn_w?pwd2ta4 提取码&#xff1a;2ta4 商品评论网站系统 小孔子内容管理系统XkCms V2.0 友间别墅整站程…

云卷云舒:数据库还能发展多少年

随着技术的发展&#xff0c;很多细分的技术领域随机消失&#xff0c;如磁带机、大/小型机等&#xff0c;数据库也能成为科技常青树吗&#xff1f; 我几个方面我来分析下&#xff1a; 1、数据库的形态变化了&#xff0c;但是并没有新一代取代旧一代&#xff0c;只是创新的一代…

【win10】解决重装系统后笔记本无法调节亮度的问题

问题描述 笔记本重装系统后发现之前的fn快捷键调节亮度的功能無了&#xff0c;检查过后发现n卡控制面板&#xff0c;电源选项这些能调节屏幕亮度的地方一个都不行。笔记本一直是最强亮度非常伤眼睛。 问题分析 重装系统后发生这种情况大概率是因为之前的显卡驱动没了&#…

【rar转zip】如何将rar文件轻松转换成zip

今天和大家分享三个rar压缩包改成zip格式的方法&#xff0c;希望能够帮助到大家&#xff01; 方法一&#xff1a; 直接修改rar压缩包的后缀名变为zip&#xff0c;就可以修改压缩包文件格式了 方法二&#xff1a; 先将rar压缩包解压出来&#xff0c;然后再将解压出的文件进行…

【MATLAB】BiGRU神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 BiGRU神经网络时序预测算法是一种基于双向门控循环单元&#xff08;GRU&#xff09;的多变量时间序列预测方法。该方法结合了双向模型和门控机制&#xff0c;旨在有效地捕捉时间序列数据中…

git 常用操作合集

✨专栏介绍 在当今数字化时代&#xff0c;Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序&#xff0c;就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术&#xff0c;以及各种框架、库和工具…

CCSK认证:开启云安全领域的黄金大门

&#x1f31f;你是否对云安全领域充满热情&#xff1f;是否希望提升自己在云安全领域的专业性和竞争力&#xff1f;CCSK认证是你的不二之选&#xff01; &#x1f525;CCSK简介&#xff1a; CCSK是国际云安全联盟&#xff08;Cloud Security Alliance&#xff0c;CSA&#xff…

【前端基础】——原型与原型链详解,看一篇即可【图文版】

前言 本文旨在通过图文的方式&#xff0c;一步步回顾原型链的整个流程是如何运作的&#xff0c;如果你刚好在电脑旁边&#xff0c;不妨跟着我的思路&#xff0c;一起走一遍敲一遍代码流程&#xff0c;你会发现原型链并没有你想的那么复杂。 new关键字 我们先看这一个代码&am…

React项目打包流程

一、React项目打包流程 一、React项目打包流程1. 项目打包打包命令&#xff1a;npm run build2. 预览接着命令行会提示执行&#xff1a; 先&#xff1a;npm install -g serve 然后执行此命令&#xff1a;serve -s build二、打包优化 - 配置路由懒加载 二、打包优化 - 配置路…

RIS 系列 See-Through-Text Grouping for Referring Image Segmentation 论文阅读笔记

RIS 系列 See-Through-Text Grouping for Referring Image Segmentation 论文阅读笔记 一、Abstract二、引言三、相关工作3.1 Semantic Segmentation and Embeddings3.2 Referring Expression Comprehension3.3 Referring Image Segmentation 四、方法4.1 视觉表示4.2 文本表示…

【yolofastest上手】

一、前言 yolofastest网上资料比较少&#xff0c;也没有视频教学&#xff0c;所以想要使用参考了很多资料&#xff0c;只能说各资料都不尽全&#xff0c;让刚接触的小白无从下手。 参考资料: github地址 yolo-fastest 快速上手 修改参数遇到的问题 能在ARM-CPU上实时识别图像的…

销售转行上位机编程:我的学习与职业经历分享

同学们好&#xff0c;我是杨工&#xff0c;原先是一名销售。 通过在华山编程培训中心学习&#xff0c;成功转行上位机编程&#xff0c;对此我想分享学习和职业经历。 在职业生涯的早期&#xff0c;我并没有考虑将技术融入到我的工作中。然而&#xff0c;在几次创业的失败后&a…

{MySQL}索引事务和JDBC

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、索引1.1索引是什么1.2作用1.3代码 二、事务2.1什么是事务2.2使用 三.JDBC总结 前言 接着上次&#xff0c;继续讲下MySQL 提示&#xff1a;以下是本篇文章正…

Jmeter吞吐量控制器总结

吞吐量控制器(Throughput Controller) 场景&#xff1a; 在同一个线程组里, 有10个并发, 7个做A业务, 3个做B业务,要模拟这种场景,可以通过吞吐量模拟器来实现。 添加吞吐量控制器 用法1: Percent Executions 在一个线程组内分别建立两个吞吐量控制器, 分别放业务A和业务B …

多浏览器密码修改,账户Token全部失效解决方案

问题场景&#xff1a; 用户在多个浏览器登录同一个账户时&#xff0c;正常情况下每个浏览器获得token应该是不同的。但若是其中一个浏览器进行了修改密码的操作&#xff0c;就应该删除该账户关联的所有token。该功能如何实现呢&#xff1f; 在这里提供一个解决方案&#xff0c;…

如何基于PyTorch框架自定义数据集类获取数据

在PyTorch框架中&#xff0c;可以通过自定义数据集类来加载和处理数据 要自定义数据集类&#xff0c;需要继承 PyTorch提供的 torch.utils.data.Dataset类&#xff0c;并实现两个主要方法&#xff1a;__len__ 和 __getitem__ 下面是一个示例&#xff0c;展示如何基于PyTorch框…

R503S指纹识别模块的通信协议

1 物理层 物理层采用串口通讯&#xff0c;波特率 57600&#xff0c;8 位数据位&#xff0c;1 位停止位&#xff0c;无奇偶校验位。 2 数据包格式 模块采用 UART 与上位机通讯&#xff0c;对命令、数据、结果的接收和发送&#xff0c;都采用数据包的形式。对于多字节的&#x…