【尚硅谷】React笔记
参考:尚硅谷React技术全家桶全套完整版(零基础入门到精通/男神天禹老师亲授)_哔哩哔哩_bilibili
GitHub - xzlaptt/React: React学习
目录
npm
Babel
React特点
jsx
组件
... 展开运算符
Refs
组件三大属性总结
props:
state:
refs:
React事件
组件通信
action
reducer
store
相关API
React事件
非受控组件
受控组件
高阶函数
函数的珂里化
新旧生命周期总结
key
Diff算法
React脚手架
react脚手架项目结构
样式模块化
组件的组合使用-TodoList
脚手架配置代理
React路由
SPA
Hooks
npm
( Node Package Manager ,即:node包管理器 )
是nodeJS的一个程序包管理和分发的管理工具,npm完全用 JavaScript 写成,
它可以让全世界与Web前端相关开发者共享代码,非常方便的使用各种插件、库和框架,
React用于构建用户界面的JS库。是一个将数据渲染为HTML视图的开源JS库。
eg:vue react Bootstrap jQuery Angular
优化开发流程的前端开发自动化构建工具: Grunt 、 Gulp 、 Webpack 、 Babel
npm包管理工具的安装及配置使用_雯倾浅忆的博客-CSDN博客_npm包管理器
Nodejs安装教程_彭佼的博客-CSDN博客_nodejs安装
Babel
JavaScript 编译器
将es6+语法转换为浏览器兼容的语法,比如将箭头函数转换为普通函数
将jsx转换成浏览器认的js
Babel是什么?Babel到底可以用来干嘛___一文带你从零开始认识Babel_zihanzy.com的博客-CSDN博客_babel是什么
React特点
jsx
注释:
html <!-- 注释 -->
js //注释 ctrl+/ /*注释*/ ctrl+shitf+/
{js表达式}
jsx {/*注释*/}
JSX语法详解_RockyHills的博客-CSDN博客_jsx语法
组件
props
组件对外公开一个简单的属性(Props),只读
通过this.props获取属性对象,主要用来传递数据
<body><div id = "div"></div></body>
<script type="text/babel">class Person extends React.Component{render(){return (<ul>//接受数据并显示<li>{this.props.name}</li><li>{this.props.age}</li><li>{this.props.sex}</li></ul>)}}//传递数据ReactDOM.render(<Person name="tom" age = "41" sex="男"/>,document.getElementById("div"));
</script>
2、Reactjs中的属性(this.props)_yubo_725的博客-CSDN博客_react this.props传递对象时
//类组件使用<script type="text/babel">class Person extends React.Component{render(){return (<ul><li>{this.props.name}</li><li>{this.props.age}</li><li>{this.props.sex}</li></ul>)}}const p = {name:"张三",age:"18",sex:"女"}ReactDOM.render(<Person {...p}/>,document.getElementById("div"));
</script>//函数组件使用
function Person(props){return (<ul><li>{props.name}</li><li>{props.age}</li><li>{props.sex}</li></ul>)}
... 展开运算符
1.主要用来展开数组
arr = [1,2,3];
arr1 = [4,5,6];
arr2 = [...arr,...arr1]; //arr2 = [1,2,,3,4,5,6]
2.复制一个对象给另一个对象(值传递)
const p1 = {name:"张三",age:"18",sex:"女"}
const p2 = {...p1};
p1.name = "sss";
console.log(p2) //{name:"张三",age:"18",sex:"女"}
3.复制时,合并属性
const p1 = {name:"张三",age:"18",sex:"女"}const p2 = {...p1,name : "111",hua:"ss"};p1.name = "sss";console.log(p2) //{name: "111", age: "18", sex: "女",hua:"ss"}
4. {...P}并不能展开一个对象
props传递一个对象,是因为babel+react使得{..p}可以展开对象,但是只有在标签中才能使用
2、Reactjs中的属性(this.props)_yubo_725的博客-CSDN博客_react this.props
state
组件的私有属性,值是对象(可以包含多个key-value的组合)
React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等。
大部分开发中用到的都是React封装的事件,比如onChange、onClick、onTouchMove等,这些事件处理程序中的setState都是异步处理的。
在 React 的 setState 函数实现中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列中延时更新,而 isBatchingUpdates 默认是 false,表示 setState 会同步更新 this.state;
当 React 在调用事件处理函数之前就会先调用函数 batchedUpdates,
batchedUpdates会把 isBatchingUpdates 修改为 true,
如果是同步更新,每一个setState对调用一个render,
并且如果多次调用setState会以最后调用的setState为准
Refs
字符串形式的ref(16.8版本以上已不推荐)
解构赋值
const {inputL}=this.refs
连续解构赋值
const {value}=this.target
<=>
const {target:{value}}=this
//将value重命名为key
const {target:{value:key}}=this
只有字符串形式时Refs才有值
回调函数形式的ref
API创建Ref
组件三大属性总结
props:
单向数据流值,父子组件间的唯一通信,不可改
1.每个组件对象都会有props(properties的简写)属性
2.组件标签的所有属性都保存在props中
3.内部读取某个属性值:this.props.propertyName
state:
React 把组件看成是一个状态机(State Machines),
只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
props
中的数据都是外界传递过来的;state
中的数据都是组件私有的;(通过Ajax获取回来的数据,一般都是私有数据)
refs:
当需要获取某一个真实的DOM元素来交互,比如文本框的聚焦、触发强制动画等
当需要操作的元素和获取的元素是同一个时,无需ref
- 给DOM元素添加ref属性
- 给类组件添加ref属性
React事件
event.target得到发生事件的Dom元素对象
<input onChange={this.saveName} type = "text" name ="username"/>saveName = (event) =>{this.setState({name:event.target.value});}
组件通信
父传子:父组件的state作为子组件的props,当父组件的state改变,子组件的props也跟着改变
祖孙,需要一层层传递,组件层级嵌套到比较深,可以使用上下文getChildContext来传递信息,这样在不需要将函数一层层往下传,任何一层的子级都可以通过this.context直接访问
子传父:父组件的函数作为子组件的props,子组件调用父组件的函数来改变state
兄弟:订阅和发布机制PubSub
发布
import Pubsub from 'pubsub-js'
export const pubsubID = 'd806a360-21aa-406e-9e5f-7f375087514f' // pubsub token
Pubsub.publish(StationStatisticsID, data)
// 或
PubSub.publishSync(StationStatisticsID, data)
PubSub.publish("订阅的消息名称",传递的数据)
订阅
import Pubsub from 'pubsub-js'
import {pubsubID} from 'xxx'componentDidMount() {/*** 订阅*/pubsub = Pubsub.subscribe(pubsubID, (msg, data) => {console.log(msg) // 这里将会输出对应设置的 pubsubIDconsole.log(data) // 这里将会输出对应设置的参数})
}
componentWillUnmount() {/*** 取消指定的订阅*/Pubsub.unsubscribe(pubsub)/*** 取消全部订阅*/PubSub.clearAllSubscriptions()
}
PubSub.subscribe("订阅的消息名称",回调函数,第一个参数是消息名称,可以使用_来占位,第二个是传递的数据})
顶层组件通信:
只是单纯的进行视图的渲染,这时候用回调,context就行,没必要用redux,用了反而影响开发速度。
redux相当于在顶层组件之上又加了一个组件
redux是一个专门用于做状态管理的JS库(不是react插件库)。
action
- 动作的对象
- 包含2个属性
- type:标识属性, 值为字符串, 唯一, 必要属性
- data:数据属性, 值类型任意, 可选属性
- 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }
reducer
- 用于初始化状态、加工状态。
- 加工时,根据旧的state和action, 产生新的state的纯函数
store
- 将state、action、reducer联系在一起的对象
- getState(): 得到state
- dispatch(action): 分发action, 触发reducer调用, 产生新的state
- subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
相关API
- Provider:让所有组件都可以得到state数据
- connect:用于包装 UI 组件生成容器组件
mapStateToprops:将外部的数据(即state对象)转换为UI组件的标签属性
mapDispatchToProps:将分发action的函数转换为UI组件的标签属性
组件之间的信息还可以通过全局事件来传递。不同页面可以通过参数传递数据,下个页面可以用location.param来获取。
React事件
非受控组件
现用现取,官方建议尽量少用ref,用多了有一定的效率影响
handleSubmit = (event) => {event.preventDefault() //阻止表单提交const {username, password} = this//拿到的是form下的username, password结点alert(`你输入的用户名是:${username.value},你输入的密码是:${password.value}`)}render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:<input ref={c => this.username = c} type="text" name="username"/>
密码:<input ref={c => this.password = c} type="password" name="password"/>
<button>登录</button>
受控组件
将输入维护到state,等需要时再从state取出来
class Login extends React.Component {//state最好要初始化状态state = {username: '', //用户名password: '' //密码}//保存用户名到状态中saveUsername = (event) => {
this.setState({username: event.target.value})}//保存密码到状态中savePassword = (event) => {
this.setState({password: event.target.value})}//表单提交的回调handleSubmit = (event) => {event.preventDefault() //阻止表单提交const {username, password} = this.state//获得的是state下的username,password值alert(`你输入的用户名是:${username},你输入的密码是:${password}`)}render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveUsername} type="text" name="username"/>
密码:<input onChange={this.savePassword} type="password" name="password"/>
<button>登录</button>
</form>)}}//渲染组件ReactDOM.render(<Login/>, document.getElementById('test'))
高阶函数
参数 或者 返回 为函数
函数的珂里化
通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
function sum(a){return(b)=>{return (c)=>{return a+b+c}}}
//保存表单数据到状态中saveFormData = (dataType, event) => {
this.setState({[dataType]: event.target.value})}用户名:<input onChange={event => this.saveFormData('username', event)} type="text" name="username"/>//珂里化 //返回一个函数saveType = (type) =>{return (event) => {this.setState({[type]:event.target.value});}}//因为事件中必须是一个函数,所以返回的也是一个函数,这样就符合规范了render() {return (<form><input onChange = {this.saveType('name')} type = "text"/><button>登录</button></form>)}}
新旧生命周期总结
React组件中包含一系列钩子函数{生命周期回调函数}
key
//index标识
person:[{id:1,name:"张三",age:18},{id:2,name:"李四",age:19}
]
//map遍历
this.state.person.map((preson,index)=>{return <li key = {index}>{preson.name}</li>
})//name标识
<button onClick={this.addObject}>点击增加对象</button>
addObject = () =>{let {person} = this.state;const p = {id:(person.length+1),name:"王五",age:20};this.setState({person:[p,...person]});
}
虚拟dom是没有input.value的值的,只有在真实虚拟dom用户输入了才显示,所以diff时候就算是一样的input
Diff算法
react生成的新虚拟DOM和旧虚拟DOM的比较规则:
如果旧的虚拟DOM中找到了与新虚拟DOM相同的key:
- 如果内容没有变化,就直接只用之前旧的真实DOM
- 如果内容发生了变化,就生成新的真实DOM
如果旧的虚拟DOM中没有找到与新虚拟DOM相同的key:
- 根据数据创建新的真实的DOM,随后渲染到页面上
React脚手架
Webpack的基本使用_sut_uestc的博客-CSDN博客
eject暴露webpack配置
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><!--%PUBLIC_URL%表示public文件夹的路径--><link rel="icon" href="%PUBLIC_URL%/favicon.ico" /><!--用于开启理想视口,用于移动端页面的适配--><meta name="viewport" content="width=device-width, initial-scale=1" /><!--用于配置浏览器地址栏的颜色(仅支持安卓手机浏览器)--><meta name="theme-color" content="#000000" /><!--描述网页信息的--><metaname="description"content="Web site created using create-react-app"/><!--用于指定网页添加到手机主屏幕后的图标(仅仅支持ios)--><link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /><!--应用加壳时候的配置文件 --><link rel="manifest" href="%PUBLIC_URL%/manifest.json" /><title>React App</title></head><body><!-- 浏览器不支持JS的运行的时候展现 --><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body>
</html>
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库的支持)
webpack-dev-server帮助本地内置服务器开启,所以不能关闭cmd
React.Component
等价于 将React中的Component取出来
const {Component}=React
//module.js//定义了一个React对象
const React={a:1,b:2}//暴露
export class Component{}
//追加一个Component属性
React.Component=Component//暴露了才能引入,默认暴露只能一个
export default React//App.js
import React,{Component} from './module'
由于普通的Js和组件都是js,所一最好组件使用jsx去展示组件(组件首字母大写)
样式模块化
两个组件中样式名称有可能会冲突,这样会根据引入App这个组件的先后顺序,后面的会覆盖前面的,
为了避免这样的样式冲突,我们采用下面的形式:
1.将css文件名修改: hello.css --- >hello.module.css
2.引入并使用的时候改变方式:
import React,{Component}from 'react'
import hello from './hello.module.css' //引入的时候给一个名称
//变量hello自动转换为对象
export default class Hello extends Component{render() {return (<h1 className={hello.title}>Hello</h1> //通过大括号进行调用)}
}
组件的组合使用-TodoList
将html复制到jsx时
注意 改缩进+标签闭合+
../返回到上级目录
回调函数:被当做参数使用的函数
js 彻底理解回调函数_dkvirus的博客-CSDN博客_js回调函数
指定事件回调时,传参时调用得返回一个函数,所以要写成高阶函数
onXxx类事件,得对应函数
脚手架配置代理
React本身只关注与页面,并不包含发送ajax请求的代码,所以一般都是集成第三方的一些库,或者自己进行封装。
推荐使用axios。
在使用的过程中很有可能会出现跨域的问题,这样就应该配置代理。
所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port), 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
方法一
在package.json中追加如下配置
"proxy":"请求的地址" "proxy":"http://localhost:5000"
说明:
- 优点:配置简单,前端请求资源时可以不加任何前缀。
- 缺点:不能配置多个代理。
- 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)
方法二
1.创建代理配置文件
在src下创建配置文件:src/setupProxy.js
2.编写setupProxy.js配置具体代理规则:
const proxy = require('http-proxy-middleware')module.exports = function(app) {app.use(proxy('/api1', { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址)changeOrigin: true, //控制服务器接收到的请求头中host字段的值/*changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000changeOrigin默认值为false,但我们一般将changeOrigin值设为true*/pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)}),proxy('/api2', { target: 'http://localhost:5001',changeOrigin: true,pathRewrite: {'^/api2': ''}})) }
说明:
- 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
- 缺点:配置繁琐,前端请求资源时必须加前缀。
React路由
SPA
单页Web应用(single page web application,SPA)。
整个应用只有一个完整的页面。
点击页面中的链接不会刷新页面,只会做页面的局部更新。
数据都需要通过ajax请求获取,并在前端异步展现
React 路由详解(超详细详解)_江北阳小皮~的博客-CSDN博客_react路由
react-router-dom v6 使用_别样红。的博客-CSDN博客_react router v6
Redirect V6 版本已经废弃,需要导入Hook钩子Navigate ,
<Routes>
{/* exact =true 开启路由精准匹配={true}可以省略 尽量不开启严格匹配*/}
<Route exact path="/about" element={<About/>}/>
<Route exact={true} path="/home" element = {<Home/>} />
<Route path="*" element={<Navigate to ="/about" />}/>
</Routes>
Hooks
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
【尚硅谷】React笔记相关推荐
- 【YY笔记】React.入门(尚硅谷React教程笔记)
前言 教程链接:尚硅谷React技术全家桶全套完整版:天禹老师讲得挺好,感谢免费分享教程 笔记用OneNote记的,不想重写了,但是想保留格式就只能用图片传上来--很烦 可能会有一些疏漏和小白的地方, ...
- 尚硅谷 jQuery 笔记(张晓飞 2018)
title: 尚硅谷 jQuery 笔记 date: 2020-11-24 21:40:50 toc: true description: jQuery是JS的一个封装的库函数集,用于DOM的CRUD ...
- Java 基础 第3阶段:高级应用——尚硅谷学习笔记(含面试题) 2023年
Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 第 9 章 异常处理 9.1 异 ...
- 尚硅谷_CSS3 笔记
目录 什么是CSS3 选择器 基本选择器及其扩展 属性选择器 伪类与伪元素选择器 css声明的优先级 自定义字体&字体图标 复习1 新的UI方案 文本新增样式 opacity RGBA 文字阴 ...
- B站MySQL(尚硅谷)学习笔记
B站MySQL基础(尚硅谷)学习笔记 最近在学习数据库技术,并且把视频中的知识点进行了汇总,字数较多,仅供参考. 会持续更新 欢迎读者提出问题与错误,一起交流~ 视频前几集所讲述的基本知识: DB:数 ...
- 尚硅谷JavaSE笔记(四)
系列文章目录 尚硅谷JavaSE笔记(一) 尚硅谷JavaSE笔记(二) 尚硅谷JavaSE笔记(三) 尚硅谷JavaSE笔记(四) 文章目录 十六.File 类与 IO 流 1.java.io.Fi ...
- 尚硅谷vue笔记 详细讲解版(尚硅谷 天禹老师)
视频:[尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通]https://www.bilibili.com/video/BV1Zy4y1K7SH?vd_source=10e3dfac9 ...
- 尚硅谷设计模式笔记-装饰者模式
文章目录 一.需求 二.装饰者方法 三.装饰者模式的JDK应用 笔记来源: 尚硅谷 一.需求 星巴克咖啡订单项目(咖啡馆) : 咖啡种类/单品咖啡: Espresso(意大利浓咖啡). ShortBl ...
- 尚硅谷springboot笔记_dubbo笔记(一、基础知识)
文章内容参考尚硅谷dubbo文档,侵删. 官方地址:https://shimo.im/docs/T9CRVXdRD9CdjcGw/ 一.SOA和RPC介绍 1.SOA 随着互联网的发展,应用规模不断扩 ...
- Maven:你还在手动导包吗?带你了解Maven的前世今生(尚硅谷详细笔记)
文章目录 一.吐槽: 二.为什么要用Maven? 2.1 真的需要吗? 2.2 究竟为什么? 三.什么是Maven? 3.1 Maven 简介 3.2 什么是构建 3.3 构建过程的几个主要环节 3. ...
最新文章
- 布隆过滤器解决缓存穿透_缓冲穿透/缓存击穿/缓存雪崩等问题解决办法
- 阿里推出 PolarFS 分布式文件系统:将存储与计算分开(附论文)
- Android8.0适配那点事(二)
- Android系统之Broadcom GPS 移植
- 物理光学10 相干光与相干性
- Sql Server 查看所有存储过程或视图的位置及内容
- Matlab快速入门
- 前端学习(2677):懂代码之表格BaseTable删除操作
- 如何匹配两段文本的语义?
- Python小项目——学生信息管理系统(详细讲解)
- 面向对象课程 - 寒假第三次作业 - C++计算器项目初始部分
- Python语法教程-基础语法01
- 浮点数 字符串 java_Java如何将浮点数转换为字符串
- 关于javascript控制系统弹出下载提示 用以下载图片
- 本地html导入印象笔记,LocalNote,让你像使用本地文件一样使用印象笔记(支持 markdown 格式)...
- 关于代付和分账系统的区别
- PHPMailer 发送163网易企业邮箱和个人邮箱, 163邮箱可能无法发送gmail邮箱,可使用qq邮箱解决问题
- 用python计算债券YTM
- Flask项目能打包为单个exe文件运行?掌握原理后居然如此简单!
- WebLogic BEA-101020问题
热门文章
- iOS备忘录之IOS开发的一些网站(看看还是不错的)
- 基于同一主机配置 Oracle 11g Data Guard
- Qt Data Visualization 3D可视化
- 51单片机C语言智能小车,基于51单片机智能小车的设计与实现
- Cadence PSpice 模型5:基于ABM库创建XC6209稳压芯片的PSpice模型实战图文教程
- 直销模式系统开发|双轨制度跟级差制度哪个模式比较好?
- 【仿真】Proteus8.9 下载与安装教程(超详细)
- java file 权限_Java文件权限(设置)
- Lwip协议详解(基于Lwip 2.1.0)-内存管理
- html 跑马灯效果 源代码,跑马灯效果.html