[尚硅谷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/>);

项目结构:

运行结果:

 

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

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

相关文章

/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21‘ not found (required by

在某项目中遇到下面的错误&#xff0c; ./model2trt_v2: /lib64/libstdc.so.6: version GLIBCXX_3.4.21 not found (required by ./model2trt_v2) ./model2trt_v2: /lib64/libstdc.so.6: version GLIBCXX_3.4.21 not found (required by ../../../lib/linux_lib/libcuda_utils…

mysql中varchar长度为多少

一. varchar存储规则&#xff1a; 4.0版本以下&#xff0c;varchar(20)&#xff0c;指的是20字节&#xff0c;如果存放UTF8汉字时&#xff0c;只能存6个&#xff08;每个汉字3字节&#xff09; 5.0版本以上&#xff0c;varchar(20)&#xff0c;指的是20字符&#xff0c;无论存…

QT之可自由折叠和展开的布局

介绍和功能分析 主要是实现控件的折叠和展开&#xff0c;类似抽屉控件&#xff0c;目前Qt自带的控件QToolBox具有这个功能&#xff0c;但是一次只能展开一个&#xff0c;所以针对自己的需求可以自己写一个类似的功能&#xff0c;这里实现的方法比较多&#xff0c;其实原理也比较…

Flink: Only supported for operators

Exception in thread "main" java.lang.UnsupportedOperationException: Only supported for operators.at org.apache.flink.streaming.api.scala.DataStream.name(

2023.10.02 win7x64sp1下Navicat_Premium15_x86连接Oracle_10g(安装在win2003x86)

Oracle_10g安装在这个版本的系统里: Microsoft Windows [版本 5.2.3790] 这个win2003_x86(分配内存1G)安装在vmware虚拟机里. 安装包文件名为:oracle 10g_win32.zip 大小约624 MB (655,025,354 字节) 安装完毕后,tcp1521端口应该开放: Microsoft Windows [版本 5.2.3790]…

C语言中volatile/register/const/static/extern/auto关键字的作用

目录 一、volatile 二、register详解 三、const详解 四、static详解 五、extern详解 语法 作用 六、auto详解 突然想总结一下这些关键字的作用&#xff0c;灵活使用这些对程序的可靠性和速率都有提高 一、volatile volatile是防止编译器优化&#xff0c;如果是高频繁…

【Spring MVC研究】DispatcherServlet如何处理请求(doDispatcher方法)

文章目录 1. 最经典的MVC的使用情况2. 经典情况相关的组件3. 执行3.1. 先看DispatcherServlet的总体过程3.2. 再看RequestMappingHandlerAdapter的总体过程3.2.1. RequestParamMethodArgumentResolver3.2.2. 反射调用 Controller 的方法3.2.3. RequestResponseBodyMethodProces…

Matlab参数估计与假设检验(举例解释)

参数估计分为点估计和区间估计&#xff0c;在matlab中可以调用namefit()函数来计算参数的极大似然估计值和置信区间。而数据分析中用得最多的是正态分布参数估计。 例1 从某厂生产的滚珠中抽取10个&#xff0c;测得滚珠的直径&#xff08;单位&#xff1a;mm&#xff09;为x[…

Git入门详解

Git入门详解 本文承接上文 Git入门简介 并做了内容扩充。本文讲述Git工具的安装、配置及使用友情参考链接&#xff1a;https://gitee.com/all-about-git 1. Git安装 安装官网&#xff1a;https://git-scm.com/安装过程如下&#xff1a; 双击.exe默认安装即可 2. Git配置 …

云安全之下一代防火墙介绍

防火墙的概念 下一代防火墙&#xff08;Next Generation Firewall&#xff0c;NGFW&#xff09;是一种可以全面应对应用层威胁的高性能防火墙。通过深入洞察网络流量中的用户、应用和内容&#xff0c;并借助全新的高性能单路径异构并行处理引擎&#xff0c;NGFW能够为用户提供…

吴恩达《微调大型语言模型》笔记

微调&#xff08;fine-tuning&#xff09;就是利用特有数据和技巧将通用模型转换为能执行具体任务的一种方式。例如&#xff0c;将 GPT-3 这种通用模型转换为诸如 ChatGPT 这样的专门用于聊天的模型。或者将 GPT-4 转换为诸如 GitHub Coplot 这样的专门用于写代码的模型。 这里…

掌握核心技巧就能创建完美的目录!如何在Word中自动创建目录

目录是Word布局的一个重要因素&#xff0c;尤其是在编写较长的文档时。那么&#xff0c;你如何在你的作品中添加目录呢&#xff1f;在这篇文章中&#xff0c;我将分享一些基于Word2016自动创建目录的经验。希望它能或多或少地帮到你。 自动创建目录 1、输入目录文本的名称&am…

【Redis】Redis中的数据结构和内部编码

Redis中的数据结构和内部编码 type命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列表&#xff09;、hash&#xff08;哈希&#xff09;、set&#xff08;集合&#xff09;、zset&#xf…

C/C++学习 -- RSA算法

概述 RSA算法是一种广泛应用于数据加密与解密的非对称加密算法。它由三位数学家&#xff08;Rivest、Shamir和Adleman&#xff09;在1977年提出&#xff0c;因此得名。RSA算法的核心原理是基于大素数的数学问题的难解性&#xff0c;利用两个密钥来完成加密和解密操作。 特点 …

第二证券:华为全液冷超充上线,高压快充概念爆发,双杰电气等涨停

受华为全液冷超充上线消息提振&#xff0c;高压快充概念9日盘中强势拉升&#xff0c;到发稿&#xff0c;双杰电气、永贵电器“20cm”涨停&#xff0c;英可瑞、易事特涨超13%&#xff0c;伊戈尔、协鑫能科、宝馨科技、日丰股份等涨停&#xff0c;万祥科技、星云股份涨近8%。 消…

禁用Chrome自动更新

chrome浏览器会强制用户自动更新&#xff0c;每次点击关于google时&#xff0c;会自动检测更新并下载&#xff0c;非常不好 1. 进入%userprofile%\AppData\Local\Google文件夹 2. 找到其中的Update文件夹&#xff0c;右键属性-安全&#xff0c;将所有组/用户的权限设置为拒绝…

计算机视觉简介(1)

任何计算机视觉处理流程都始于成像系统&#xff0c;它从景物中捕获反射出来的光线&#xff0c;并将光信号转换成计算机可以读取和处理的图像格式 在计算机成像技术发展的早期&#xff0c;图像通过把胶卷或印刷图像素 化后获得&#xff1b;而现在图 像通常直接由数码相机获取&a…

ubuntu编译安装并测试opencv

下载opencv工程 git clone https://github.com/opencv/opencv.git git -C opencv checkout 4.x构建并编译opencv 在build目录下使用cmake构建生成makefile cd opencv mkdir -p build && cd build cmake -D CMAKE_BUILD_TYPERelease -D OPENCV_GENERATE_PKGCONFIGON …

elementplus下载表格为excel格式

安装xlsx npm i --save https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz引入xlsx并使用 import XLSX from xlsx;const tableRef ref<any>(null); // 导出为 Excel const exportToExcel () > {// 获取 el-table 的引用tableRef.value tableRef.value || doc…

Python Loguru 日志打印

在开发过程中&#xff0c;我们经常需要记录应用程序的运行状态和错误信息。日志是一种重要的工具&#xff0c;可以帮助我们快速定位和解决问题。Python3提供了多种日志库&#xff0c;其中Loguru是一个简单易用的日志库&#xff0c;它提供了丰富的功能和灵活的配置选项&#xff…