【尚硅谷】React笔记

【尚硅谷】React笔记,第1张

 参考:尚硅谷React技术全家桶全套完整版(零基础入门到精通/男神天禹老师亲授)_哔哩哔哩_bilibili

GitHub - xzlaptt/React: React学习

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获取属性对象,主要用来传递数据


    

    


2、Reactjs中的属性(this.props)_yubo_725的博客-CSDN博客_react this.props传递对象时

//类组件使用



//函数组件使用
function Person(props){
          return (
                
                    {props.name}
                    {props.age}
                    {props.sex}
                
            )
    }
... 展开运算符

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元素对象



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) // 这里将会输出对应设置的 pubsubID
		console.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 用于初始化状态、加工状态。加工时,根据旧的stateaction 产生新的state纯函数 store stateactionreducer联系在一起的对象getState(): 得到state dispatch(action): 分发action, 触发reducer调用, 产生新的statesubscribe(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 (

            )
        }
    }

//渲染组件
    ReactDOM.render(, document.getElementById('test'))
高阶函数

参数  或者  返回 为函数

函数的珂里化

通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式

  function sum(a){
                     return(b)=>{
                        return (c)=>{
                           return a+b+c
                        }
                     }
                  }

//保存表单数据到状态中
        saveFormData = (dataType, event) => {
this.setState({[dataType]: event.target.value})
        }

用户名: this.saveFormData('username', event)} type="text" name="username"/>


//珂里化	
		//返回一个函数
        saveType = (type) =>{
            return (event) => {
                this.setState({[type]:event.target.value});
            }
        }

        //因为事件中必须是一个函数,所以返回的也是一个函数,这样就符合规范了
        render() {
            return (
                
            )
        }
    }
新旧生命周期总结

 React组件中包含一系列钩子函数{生命周期回调函数}

key
//index标识
person:[
    {id:1,name:"张三",age:18},
    {id:2,name:"李四",age:19}
]
//map遍历
this.state.person.map((preson,index)=>{
  return  {preson.name}
})


//name标识

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配置



  
    
    
    
    
    
    
    
    
    
    
    
 
    
    
  
    React App
  
  
    
    
    
  

 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 (
            Hello   //通过大括号进行调用
        )
    }
}
组件的组合使用-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:5000
      	changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
      	changeOrigin默认值为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 ,

{/* exact =true 开启路由精准匹配={true}可以省略 尽量不开启严格匹配*/}

} />
}/>

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/944598.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-18
下一篇2022-05-18

发表评论

登录后才能评论

评论列表(0条)

    保存