当前位置: 首页 > news >正文

[尚硅谷React笔记]——第3章 React应用(基于React脚手架)

目录:

  1. react脚手架
  2. 创建项目并启动
  3. react脚手架项目结构
  4. 一个简单的Hello组件
  5. 样式的模块化
  6. 功能界面的组件化编码流程(通用)
  7. 组件的组合使用-TodoList  

1.react脚手架

  1. xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
    1. 包含了所有需要的配置(语法检查、jsx编译、devServer…)
    2. 下载好了所有相关的依赖
    3. 可以直接运行一个简单效果
  2. react提供了一个用于创建react项目的脚手架库: create-react-app
  3. 项目的整体技术架构为:  react + webpack + es6 + eslint
  4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

2.创建项目并启动

  1. 全局安装:npm i -g create-react-app
  2. 切换到想创项目的目录,使用命令:create-react-app hello-react
  3. 进入项目文件夹:cd hello-react
  4. 启动项目: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.功能界面的组件化编码流程(通用)

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件: 使用组件实现静态页面效果
  3. 实现动态组件
    1. 动态显示初始化数据
      1. 数据类型
      2. 数据名称
      3. 保存在哪个组件?
    2. 交互(从绑定事件监听开始)

7.组件的组合使用-TodoList  

todoList案例相关知识点

  1. 拆分组件、实现静态组件,注意: className、style的写法
  2. 动态初始化列表,如何确定将数据放在哪个组件的state中?
    1. 某个组件使用放在自身的state中
    2. 某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升
  3. 关于父子之间通信:
    1. 【父组件】给【子组件】传递数据:通过props传递
    2. 【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递
  4. 注意defaultchecked 和 checked的区别,类似的还有: defaultValue 和 value
  5. 状态在哪里,操作状态的方法就在哪里

 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脚手架)

目录&#xff1a; react脚手架创建项目并启动react脚手架项目结构一个简单的Hello组件样式的模块化功能界面的组件化编码流程&#xff08;通用&#xff09;组件的组合使用-TodoList 1.react脚手架 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需…...

《Linux 内核设计与实现》13. 虚拟文件系统

通用文件接口 VFS 使得可以直接使用 open()、read()、write() 这样的系统调用而无需考虑具体文件系统和实际物理介质。 好处&#xff1a;新的文件系统和新类型的存储介质需要挂载时&#xff0c;程序无需重写&#xff0c;甚至无需重新编译。 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; } 没有换行&#xff0c;不然会格式错误 第二题 #include<stdio.h>int main() {int a;s…...

JMeter学习第一、二、三天

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

常用的分布式ID解决方案原理解析

目录 前言 一&#xff1a;分布式ID的使用场景 二&#xff1a;分布式ID设计的技术指标 三&#xff1a;常见的分布式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 || ""…...

分布式主键算法

目录 一、引言二、常见算法介绍雪花算法&#xff08;Snowflake Algorithm&#xff09;特性详解优势劣势 UUID&#xff08;Universally Unique Identifier&#xff09;特性详解优势劣势 数据库自增主键特性详解优势劣势 分布式数据库的序列&#xff08;Sequence&#xff09;特性…...

暴力破解及验证码安全

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

程序无法启动,提示“找不到msvcp140.dll”或“msvcp140.dll缺失报错”解决方法

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

【Python查找算法】二分查找、线性查找、哈希查找

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

【MySQL实战45讲-基础篇】

基础篇 基础架构 MySQL的基本架构示意图&#xff1a;MySQL可以分为Server层和存储引擎层两部分。 Server层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖MySQL的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函…...

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)) 持久代&#xff1a; JVM用持久带&#xff08;Permanent Space&#xff09;实现方法…...

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…...

掌动智能:性能压力测试的重要性

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

kafka日志文件详解及生产常见问题总结

一、kafka的log日志梳理 日志文件是kafka根目录下的config/server.properties文件&#xff0c;配置log.dirs/usr/local/kafka/kafka-logs&#xff0c;kafka一部分数据包含当前Broker节点的消息数据(在Kafka中称为Log日志)&#xff0c;称为无状态数据&#xff0c;另外一部分存在…...

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"&#xff1a; 指名工程名、使用的JDK版本等信息。如下所示&#xff1a; 接着创建Java类&#xff1a; 2 编写代码 public class HelloWorld {public static void main(S…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...