参考:尚硅谷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

  1. 动作的对象
  2. 包含2个属性
    1. type:标识属性, 值为字符串, 唯一, 必要属性
    2. data:数据属性, 值类型任意, 可选属性
  3. 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }

reducer

  1. 用于初始化状态、加工状态。
  2. 加工时,根据旧的state和action, 产生新的state的纯函数

store

  1. 将state、action、reducer联系在一起的对象
  2. getState(): 得到state
    1. dispatch(action): 分发action, 触发reducer调用, 产生新的state
    2. subscribe(listener): 注册监听, 当产生了新的state时, 自动调用

相关API

  1. Provider:让所有组件都可以得到state数据

  1. 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"  

说明:

  1. 优点:配置简单,前端请求资源时可以不加任何前缀。
  2. 缺点:不能配置多个代理。
  3. 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)

方法二

1.创建代理配置文件

在src下创建配置文件:src/setupProxy.js
  1. 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': ''}}))
    }

说明:

  1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
  2. 缺点:配置繁琐,前端请求资源时必须加前缀。

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笔记相关推荐

  1. 【YY笔记】React.入门(尚硅谷React教程笔记)

    前言 教程链接:尚硅谷React技术全家桶全套完整版:天禹老师讲得挺好,感谢免费分享教程 笔记用OneNote记的,不想重写了,但是想保留格式就只能用图片传上来--很烦 可能会有一些疏漏和小白的地方, ...

  2. 尚硅谷 jQuery 笔记(张晓飞 2018)

    title: 尚硅谷 jQuery 笔记 date: 2020-11-24 21:40:50 toc: true description: jQuery是JS的一个封装的库函数集,用于DOM的CRUD ...

  3. Java 基础 第3阶段:高级应用——尚硅谷学习笔记(含面试题) 2023年

    Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 第 9 章 异常处理 9.1 异 ...

  4. 尚硅谷_CSS3 笔记

    目录 什么是CSS3 选择器 基本选择器及其扩展 属性选择器 伪类与伪元素选择器 css声明的优先级 自定义字体&字体图标 复习1 新的UI方案 文本新增样式 opacity RGBA 文字阴 ...

  5. B站MySQL(尚硅谷)学习笔记

    B站MySQL基础(尚硅谷)学习笔记 最近在学习数据库技术,并且把视频中的知识点进行了汇总,字数较多,仅供参考. 会持续更新 欢迎读者提出问题与错误,一起交流~ 视频前几集所讲述的基本知识: DB:数 ...

  6. 尚硅谷JavaSE笔记(四)

    系列文章目录 尚硅谷JavaSE笔记(一) 尚硅谷JavaSE笔记(二) 尚硅谷JavaSE笔记(三) 尚硅谷JavaSE笔记(四) 文章目录 十六.File 类与 IO 流 1.java.io.Fi ...

  7. 尚硅谷vue笔记 详细讲解版(尚硅谷 天禹老师)

    视频:[尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通]https://www.bilibili.com/video/BV1Zy4y1K7SH?vd_source=10e3dfac9 ...

  8. 尚硅谷设计模式笔记-装饰者模式

    文章目录 一.需求 二.装饰者方法 三.装饰者模式的JDK应用 笔记来源: 尚硅谷 一.需求 星巴克咖啡订单项目(咖啡馆) : 咖啡种类/单品咖啡: Espresso(意大利浓咖啡). ShortBl ...

  9. 尚硅谷springboot笔记_dubbo笔记(一、基础知识)

    文章内容参考尚硅谷dubbo文档,侵删. 官方地址:https://shimo.im/docs/T9CRVXdRD9CdjcGw/ 一.SOA和RPC介绍 1.SOA 随着互联网的发展,应用规模不断扩 ...

  10. Maven:你还在手动导包吗?带你了解Maven的前世今生(尚硅谷详细笔记)

    文章目录 一.吐槽: 二.为什么要用Maven? 2.1 真的需要吗? 2.2 究竟为什么? 三.什么是Maven? 3.1 Maven 简介 3.2 什么是构建 3.3 构建过程的几个主要环节 3. ...

最新文章

  1. 布隆过滤器解决缓存穿透_缓冲穿透/缓存击穿/缓存雪崩等问题解决办法
  2. 阿里推出 PolarFS 分布式文件系统:将存储与计算分开(附论文)
  3. Android8.0适配那点事(二)
  4. Android系统之Broadcom GPS 移植
  5. 物理光学10 相干光与相干性
  6. Sql Server 查看所有存储过程或视图的位置及内容
  7. Matlab快速入门
  8. 前端学习(2677):懂代码之表格BaseTable删除操作
  9. 如何匹配两段文本的语义?
  10. Python小项目——学生信息管理系统(详细讲解)
  11. 面向对象课程 - 寒假第三次作业 - C++计算器项目初始部分
  12. Python语法教程-基础语法01
  13. 浮点数 字符串 java_Java如何将浮点数转换为字符串
  14. 关于javascript控制系统弹出下载提示 用以下载图片
  15. 本地html导入印象笔记,LocalNote,让你像使用本地文件一样使用印象笔记(支持 markdown 格式)...
  16. 关于代付和分账系统的区别
  17. PHPMailer 发送163网易企业邮箱和个人邮箱, 163邮箱可能无法发送gmail邮箱,可使用qq邮箱解决问题
  18. 用python计算债券YTM
  19. Flask项目能打包为单个exe文件运行?掌握原理后居然如此简单!
  20. WebLogic BEA-101020问题

热门文章

  1. iOS备忘录之IOS开发的一些网站(看看还是不错的)
  2. 基于同一主机配置 Oracle 11g Data Guard
  3. Qt Data Visualization 3D可视化
  4. 51单片机C语言智能小车,基于51单片机智能小车的设计与实现
  5. Cadence PSpice 模型5:基于ABM库创建XC6209稳压芯片的PSpice模型实战图文教程
  6. 直销模式系统开发|双轨制度跟级差制度哪个模式比较好?
  7. 【仿真】Proteus8.9 下载与安装教程(超详细)
  8. java file 权限_Java文件权限(设置)
  9. Lwip协议详解(基于Lwip 2.1.0)-内存管理
  10. html 跑马灯效果 源代码,跑马灯效果.html