[尚硅谷React笔记]——第3章 React应用(基于React脚手架)
目录:
- react脚手架
- 创建项目并启动
- react脚手架项目结构
- 一个简单的Hello组件
- 样式的模块化
- 功能界面的组件化编码流程(通用)
- 组件的组合使用-TodoList
1.react脚手架
- xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
- 包含了所有需要的配置(语法检查、jsx编译、devServer…)
- 下载好了所有相关的依赖
- 可以直接运行一个简单效果
- react提供了一个用于创建react项目的脚手架库: create-react-app
- 项目的整体技术架构为: react + webpack + es6 + eslint
- 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化
2.创建项目并启动
- 全局安装:npm i -g create-react-app
- 切换到想创项目的目录,使用命令:create-react-app hello-react
- 进入项目文件夹:cd hello-react
- 启动项目:npm start
3.react脚手架项目结构
public ---- 静态资源文件夹
favicon.icon ------ 网站页签图标
index.html -------- 主页面
logo192.png ------- logo图
logo512.png ------- logo图
manifest.json ----- 应用加壳的配置文件
robots.txt -------- 爬虫协议文件
src ---- 源码文件夹
App.css -------- App组件的样式
App.js --------- App组件
App.test.js ---- 用于给App做测试
index.css ------ 样式
index.js ------- 入口文件
logo.svg ------- logo图
reportWebVitals.js --- 页面性能分析文件(需要web-vitals库的支持)
setupTests.js ---- 组件单元测试的文件(需要jest-dom库的支持)
4.一个简单的Hello组件
Hello.jsx
import React, {Component} from 'react'
import './Hello.css'export default class Hello extends Component {render() {return <h2 className="title">hello,react!</h2>}
}
Hello.css
.title {background-color: orange;
}
Welcome.jsx
import React, {Component} from "react";
import './Welcome.css'export default class Welcome extends Component {render() {return <h2 className="demo">welcome</h2>}
}
Welcome.css
.demo {background-color: skyblue;
}
App.js
import React from 'react'
import Hello from "./components/Hello/Hello";
import Welcome from "./components/Welcome/Welcome";export default class App extends React.Component {render() {return (<div><Hello></Hello><Welcome></Welcome></div>)}
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
运行结果:
5.样式的模块化
Hello.jsx
import React, {Component} from 'react'
import hellocss from './Hello.module.css'export default class Hello extends Component {render() {return <h2 className={hellocss.title}>hello,react!</h2>}
}
Hello.module.css
.title {background-color: orange;
}
Welcome.jsx
import React, {Component} from "react";
import welcomecss from './Welcome.module.css'export default class Welcome extends Component {render() {return <h2 className={welcomecss.title}>welcome</h2>}
}
Welcome.module.css
.title {background-color: skyblue;
}
运行结果:
6.功能界面的组件化编码流程(通用)
- 拆分组件: 拆分界面,抽取组件
- 实现静态组件: 使用组件实现静态页面效果
- 实现动态组件
- 动态显示初始化数据
- 数据类型
- 数据名称
- 保存在哪个组件?
- 交互(从绑定事件监听开始)
- 动态显示初始化数据
7.组件的组合使用-TodoList
todoList案例相关知识点
- 拆分组件、实现静态组件,注意: className、style的写法
- 动态初始化列表,如何确定将数据放在哪个组件的state中?
- 某个组件使用放在自身的state中
- 某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升
- 关于父子之间通信:
- 【父组件】给【子组件】传递数据:通过props传递
- 【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递
- 注意defaultchecked 和 checked的区别,类似的还有: defaultValue 和 value
- 状态在哪里,操作状态的方法就在哪里
Footer.css
/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;
}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;
}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;
}.todo-footer button {float: right;margin-top: 5px;
}
Footer.jsx
import React, {Component} from 'react';
import './Footer.css'class Footer extends Component {handleCheckAll = (event) => {this.props.checkAllTodo(event.target.checked)}handleClearAllDone = () => {this.props.clearAllDone()}render() {const {todos} = this.propsconst doneCount = todos.reduce((pre, current) => {return pre + (current.done ? 1 : 0)}, 0)const total = todos.lengthreturn (<div className="todo-footer"><label><input type="checkbox" onChange={this.handleCheckAll}checked={doneCount === total && total !== 0 ? true : false}/></label><span><span>已完成{doneCount}</span> / 全部{total}</span><button onClick={this.handleClearAllDone} className="btn btn-danger">清除已完成任务</button></div>);}
}export default Footer;
Header.css
/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;
}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}
Header.jsx
import React, {Component} from 'react';
import PropTypes from 'prop-types'
import {nanoid} from "nanoid";
import './Header.css'class Header extends Component {static propTypes = {addTodo: PropTypes.func.isRequired}handleKeyUp = (event) => {const {keyCode, target} = eventif (keyCode != 13) returnif (target.value.trim() == '') {alert('输入不能为空')return;}const todoObj = {id: nanoid(), name: target.value, done: false}this.props.addTodo(todoObj)target.value = ''}render() {return (<div className="todo-header"><input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认"/></div>);}
}export default Header;
Item.css
/*item*/
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;
}li label {float: left;cursor: pointer;
}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;
}li button {float: right;display: none;margin-top: 3px;
}li:before {content: initial;
}li:last-child {border-bottom: none;
}
Item.jsx
import React, {Component} from 'react';
import './Item.css'class Item extends Component {state = {mouse: false}handelMouse = (flag) => {return () => {this.setState({mouse: flag})}}handleCheck = (id) => {return (event) => {this.props.updateTodo(id, event.target.checked)}}handleDelete = (id) => {if (window.confirm('确定删除吗?')) {this.props.deleteTodo(id)}}render() {const {id, name, done} = this.propsconst {mouse} = this.statereturn (<li style={{backgroundColor: mouse ? '#ddd' : 'white'}} onMouseEnter={this.handelMouse(true)}onMouseLeave={this.handelMouse(false)}><label><input type="checkbox" checked={done} onChange={this.handleCheck(id)}/><span>{name}</span></label><button onClick={() => {this.handleDelete(id)}}className="btn btn-danger"style={{display: mouse ? 'block' : 'none'}}>删除</button></li>);}
}export default Item;
List.css
/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;
}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;
}
List.jsx
import React, {Component} from 'react';
import PropTypes from "prop-types";
import Item from "../Item/Item";
import './List.css'class List extends Component {static propTypes = {todos: PropTypes.array.isRequired,updateTodo: PropTypes.func.isRequired,deleteTodo: PropTypes.func.isRequired}render() {const {todos, updateTodo, deleteTodo} = this.propsreturn (<ul className="todo-main">{todos.map((todo) => {return <Item key={todo.id} {...todo} updateTodo={updateTodo} deleteTodo={deleteTodo}></Item>})}</ul>);}
}export default List;
App.css
/*base*/
body {background: #fff;
}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;
}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;
}.btn-danger:hover {color: #fff;background-color: #bd362f;
}.btn:focus {outline: none;
}.todo-container {width: 600px;margin: 0 auto;
}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}
App.js
import React, {Component} from 'react';
import './App.css'
import Header from "./components/Header/Header";
import Footer from "./components/Footer/Footer";
import List from "./components/List/List";class App extends Component {//初始化状态state = {todos: [{id: '001', name: '吃饭', done: true},{id: '002', name: '睡觉', done: true},{id: '003', name: '打代码', done: false},{id: '004', name: '逛街', done: true},]}addTodo = (todoObj) => {const {todos} = this.stateconst newTodos = [todoObj, ...todos]this.setState({todos: newTodos})}updateTodo = (id, done) => {const {todos} = this.stateconst newTodos = todos.map((todoObj) => {if (todoObj.id === id) {return {...todoObj, done: done}} else {return todoObj}})this.setState({todos: newTodos})}deleteTodo = (id) => {const {todos} = this.stateconst newTodos = todos.filter((todoObj) => {return todoObj.id !== id})this.setState({todos: newTodos})}checkAllTodo = (done) => {const {todos} = this.stateconst newTodos = todos.map((todoObj) => {return {...todoObj, done: done}})this.setState({todos: newTodos})}clearAllDone = () => {const {todos} = this.stateconst newTodos = todos.filter((todoObj) => {return !todoObj.done})this.setState({todos: newTodos})}render() {return (<div className="todo-container"><div className="todo-wrap"><Header addTodo={this.addTodo}></Header><List todos={this.state.todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}></List><Footer todos={this.state.todos}checkAllTodo={this.checkAllTodo}clearAllDone={this.clearAllDone}></Footer></div></div>);}
}export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
项目结构:
‘’
运行结果:
相关文章:

[尚硅谷React笔记]——第3章 React应用(基于React脚手架)
目录: react脚手架创建项目并启动react脚手架项目结构一个简单的Hello组件样式的模块化功能界面的组件化编码流程(通用)组件的组合使用-TodoList 1.react脚手架 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需…...

《Linux 内核设计与实现》13. 虚拟文件系统
通用文件接口 VFS 使得可以直接使用 open()、read()、write() 这样的系统调用而无需考虑具体文件系统和实际物理介质。 好处:新的文件系统和新类型的存储介质需要挂载时,程序无需重写,甚至无需重新编译。 VFS 将各种不同的文件系统抽象后采…...

2021-06-09 51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次
缘由51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次_嵌入式-CSDN问答 #include "REG52.h" sbit K1 P1^0; sbit K2 P1^1; sbit LEDP0^0; void main() {unsigned char Xd0,ss0;unsigned int wei0;while(1){if(K10&&Xd0){ss3*2;…...
C/C++ 经典面试算法题
1.打印杨辉三角 1 #include <stdio.h>2 #include <string.h>3 4 int main()5 {6 int x;7 int a[100][100];8 printf("输入行数\n");9 scanf("%d",&x); 10 for(int i 0;i<x;i) 11 { 12 for(int j 0;…...
2023年下学期《C语言》作业0x02-分支 XTU OJ 1068 1069 1070 1071 1072
第一题 #include<stdio.h>int main() {int a;scanf("%d",&a);if(a>90&&a<100) printf("A");else printf("B");return 0; } 没有换行,不然会格式错误 第二题 #include<stdio.h>int main() {int a;s…...

JMeter学习第一、二、三天
首先,我们来了解一下到底什么是接口测试与性能测试: 接口测试 定义 接口测试主要关注系统组件之间的交互,确保各个接口按预期工作。这包括验证传递的数据、数据格式、调用的频率和其他与接口调用相关的任何限制。 目的 确保系统的各个组件可…...

常用的分布式ID解决方案原理解析
目录 前言 一:分布式ID的使用场景 二:分布式ID设计的技术指标 三:常见的分布式ID生成策略 3.1 UUID 3.2 数据库生成 3.3 数据库的多主模式 3.4 号段模式 3.5 雪花算法 前言 分布式ID的生成是分布式系统中非常核心的基础性模块&#…...
echarts3D地图打点
1、echarts地图打点加鼠标移上去显示文字 2、1-3和前面的一样echart3D地图 if (res.code 0) {const resData res.data || [];if (resData.length > 0) {for (var i 0; i < resData.length; i) {let arr new Array(2);arr[0] resData[i].longitude || ""…...
分布式主键算法
目录 一、引言二、常见算法介绍雪花算法(Snowflake Algorithm)特性详解优势劣势 UUID(Universally Unique Identifier)特性详解优势劣势 数据库自增主键特性详解优势劣势 分布式数据库的序列(Sequence)特性…...

暴力破解及验证码安全
1.暴力破解注意事项 1、破解前一定要有一个有郊的字典(Top100 TOP2000 csdn QQ 163等密码) https://www.bugku.com/mima/ 密码生成器 2、判断用户是否设置了复杂的密码 在注册页面注册一个,用简单密码看是否可以注册成功 3、网站是…...

程序无法启动,提示“找不到msvcp140.dll”或“msvcp140.dll缺失报错”解决方法
大家好!今天我来给大家分享一下msvcp140.dll丢失的解决方法。我们都知道,在运行一些软件或游戏时,经常会遇到“找不到msvcp140.dll”的错误提示,这会让我们非常苦恼。那么,这个问题该怎么解决呢?下面我将为…...

【Python查找算法】二分查找、线性查找、哈希查找
目录 1 二分查找算法 2 线性查找算法 3 哈希查找算法 1 二分查找算法 二分查找(Binary Search)是一种用于在有序数据集合中查找特定元素的高效算法。它的工作原理基于将数据集合分成两半,然后逐步缩小搜索范围,直到找到目标元素…...

【MySQL实战45讲-基础篇】
基础篇 基础架构 MySQL的基本架构示意图:MySQL可以分为Server层和存储引擎层两部分。 Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函…...
asp.net core中间件预防防止xss攻击
using System; using System.Text.Json; using System.Text.Json.Serialization;namespace CommonUtils {/// <summary>/// newtonsoft的转化器/// 防止xss攻击/// </summary>public class AntiXssNewtonsoftConverter : Newtonsoft.Json.JsonConverter<string&…...

jvm概述
1、JVM体系结构 2、JVM运行时数据区 3、JVM内存模型 JVM运行时内存 共享内存区 线程内存区 3.1、共享内存区 共享内存区 持久带(方法区 其他) 堆(Old Space Young Space(den S0 S1)) 持久代: JVM用持久带(Permanent Space)实现方法…...

C++简单上手helloworld 以及 vscode找不到文件的可能性原因
helloworld #include <iostream>int main() {std::cout << "hello world!" << std::endl;return 0; }输入输出小功能 #include <iostream> using namespace std; /* *主函数 *输出一条语句 */int main() {// 输出一条语句cout << &q…...

掌动智能:性能压力测试的重要性
采用性能压力测试可以帮助企业预估系统容量、提升用户体验以及降低风险和成本。在软件开发过程中,将性能压力测试纳入测试策略的重要一环,将为企业的成功和用户满意度打下坚实的基础。 性能压力测试的重要性: 一、发现性能瓶颈 性能压力测试能…...

kafka日志文件详解及生产常见问题总结
一、kafka的log日志梳理 日志文件是kafka根目录下的config/server.properties文件,配置log.dirs/usr/local/kafka/kafka-logs,kafka一部分数据包含当前Broker节点的消息数据(在Kafka中称为Log日志),称为无状态数据,另外一部分存在…...
Linux-Centos中配置docker
1.安装yum工具 yum install -y yum-utils 2.配置yam源头 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 3.安装docker yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 4. 查看d…...

IDEA-2023-jdk8 HelloWorld的实现
目录 1 新建Project - Class 2 编写代码 3 运行 1 新建Project - Class 选择"New Project": 指名工程名、使用的JDK版本等信息。如下所示: 接着创建Java类: 2 编写代码 public class HelloWorld {public static void main(S…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...