react中配置代理方式
一、 配置 package.json
- 在package.json中,添加
proxy
配置项。之后所有请求都会指向这个地址。
"proxy":"https://localhost:5000"
需要重启项目
二、setupProxy.js
- 在项目根目录处创建
setupProxy.js
const {createProxyMiddleware} = require('http-proxy-middleware')
module.exports = function(app){
app.use(
createProxyMiddleware('/api',{// 遇见 /api 前缀的请求,就会触发该代理配置
target:'http://localhost:5000',// 请求转发给谁
changeOrigin:true,//控制服务器收到的响应头中Host字段的值
pathRewrite:{
'^/api':''//重新请求路径
}
}),
)
}
123456789101112
此时,上述url
需改为/api/demo
,当请求发送时会将/api
的前缀自动改写成http://localhost:5000
常用APi介绍
更新api介绍
forceUpdate
- 强制更新,会跳过
shouldComponentUpdate
直接更新
// 强制更新,会跳过 shouldComponentUpdate 直接更新
this.forceUpdate();
this.setState({
sum: this.state.opposed + this.state.sum,
opposed: this.state.opposed + 1,
});
在实际中,不建议,太强硬了
componentDidUpdate
- 组件更新完成
// 组件更新完成
componentDidUpdate(
prevProps: Readonly<{}>,
prevState: Readonly<{}>,
snapshot?: any
): void {
console.log("最后渲染");
}
componentDidMount
- 组件刚挂载时
componentDidMount(): void {
console.log(2);
}
shouldComponentUpdate
shouldComponentUpdate(nextProps,nextState){
// nextState:存储修改的最新状态
// this.stae:存储的是修改前的状态[此时状态还没有改变]
console.log(this.state,nextState);
// 此周期函数需要返回 true/false
// 返回true:允许更新,会继续执行下一个操作
// 返回false:不允许更新,接下来都不处理
return true;
}
组件第一次渲染完成后,无法基于内部的某些操作让组件更新【自更新】但是如果调用它的父组件更新了,那么相关子组件也一定会更新【可能传递最新的属性值进来】
函数组件渲染速度快
类组件是:动态组件
- 组件在第一渲染完毕后,除了父组件更新可以通过
this.setState
修改状态或者this.forceUpdate
等方式让组件实现自更新- 类组件具备:属性、状态、周期函数、re、【几乎组件应该有的都具备】
类组件功能强大
父子组件更新流程
- 深度有限原则
父组件第一次渲染
父
willMount
->父render
->子willMount
->子render
->didMount
->父didMount
子组件第一次渲染
父
shouldUpdate
->父willUpdate
->父render
->子shouldUpdate
->子willUpdate
->子render
->子didUpdate
->父didUpdae
Component
和PureComponent
Component
会触发更新时重新渲染*PureComponent*
纯净的,当视图更新时不会触发页面更新
- 在周期中,对新老属性/状态 会做一个浅比较
- 如果经过浅比较,发现属性和状态并没有改变,则返回false【也就是不继续更新组件】才会有变化
PureComponent
- 会默认加一个
shouldComponentUpdate
周期函数
受控和非受控组件
介绍
- 受控组件:基于修改数据/状态,达到需要的效果【推荐使用】
- 非受控组件:基于ref获取DOM元素,我们操作DOM元素,来实现需求和效果【偶尔】
基于ref获取DOM
给DOM设置ref
refs方式
- 给需要获取元素设置
ref=xxx
后期基于获取响应的DOM元素【不推荐使用】
import React, { Component, createRef } from "react";
export default class Demo2 extends Component {
titleBox = createRef();
componentDidMount(): void {
console.log(this.titleBox);
}
render() {
return (
<>
<h1 className="title" ref="titleBox">
温馨提示
</h1>
</>
);
}
}
如果使用
ref
并且后面接的是字符串,那么会将这个值添加到当前的this.refs
中,获取当前的this.refs
既可拿到当前的DOM元素但是这种方式不被推荐使用,有幸能问题,如果字符串过长等
通过this直接获取
- 直接将值赋值给当前类,通过
即可获取
import React, { Component, createRef } from "react";
export default class Demo2 extends Component {
titleBox = "";
box = createRef();
componentDidMount(): void {
console.log(this.box);
}
render() {
return (
<>
<h1 className="title" ref={(x: any) => (this.titleBox = x)}>
友情提示
</h1>
</>
);
}
}
创建createRef()
获取
- 把ref属性设置为一个函数
x
是函数的形参:存储的是当前DOM元素- 然后获取ODM元素的
x
直接拿到实例某个属性上(例如:box2)
- 需要通过
.current
import React, { Component, createRef } from "react";
export default class Demo2 extends Component {
titleBox = "";
box = createRef();
componentDidMount(): void {
console.log(this.box.current);
}
render() {
return (
<>
<h1 className="title" ref={this.box as any}>
友情提示1
</h1>
</>
);
}
}
current
默认值是null
如果给类组件设置ref
- 给类组件设置ref获取的是实例
给函数组件设置ref
- 给函数组件设置ref,直接报错
- 但是我们可以让其配合
React.forwardRef
实现ref转发 - 目的:获取函数组件内部的某个元素
- 但是我们可以让其配合
setState
回调方式
- 其中回调函数执行是在组件全部更新完成之后才去做
- 如果在状态中同时修改三个值,回调会执行一次
this.setState(
{
...
},
() => {
console.log("组件更新完成");
}
);
特殊点:基于
shouldComponentUpdate
阻止了状态/视图的更新,DidUpdate
周期函数肯定不会执行,但是设置的这个callback
回调函数依然会执行
注意
在React18中,setState操作都是异步的,不论是在那执行,。例如:合成事件、周期函数、定时器。。。。
- 目的:实现状态的批处理【统一处理】
- 有效管理代码执行的逻辑顺序
。。。
原理:利用更新队列[updater机制处理的
- 在当前相同时间短内【浏览器可以处理的事情中],遇到setState会立即放入到更新队列中
- 此时状态/视图还会更新
- 当前所有的代码操作结束,刷新队列【通知更新队列会回调执行】,把所有任务放在一起执行,只触发一次视图更新
合成事件
合成事件语法
- 基于React内部处理,如果我们合成事件绑定一个普通函数,当事件触发,绑定的函数执行,方法中this会是
undefined
不写箭头函数的this
- 如果不写箭头函数,直接调用函数会输出
undefined
import React, { Component } from "react";
export default class Demo5 extends Component {
handel() {
console.log(666);
console.log(this);// 输出 undefined
}
render() {
return (
<div>
<button onClick={this.handel}>按钮</button>
</div>
);
}
}
不写箭头函数,会输出
undefined
解决这个问题可有使用bind
方法绑定想要的this
解决方式-bind
- 通过
bind
来绑定当前的this
import React, { Component } from "react";
export default class Demo5 extends Component {
handel() {
console.log(666);
console.log(this); // 输出 undefined
}
render() {
return (
<div>
<button onClick={this.handel.bind(this)}>按钮</button>
</div>
);
}
}
写箭头函数
- 直接调用函数时,就可以直接拿到需要的值
import React, { Component } from "react";
export default class Demo5 extends Component {
handel2 = () => {
console.log("第二个按钮");
console.log(this); // 输出 undefined
};
render() {
return (
<button onClick={this.handel2}>按钮</button>
);
}
}
合成事件原理
<div
className="inner"
onClick={(ev) => {
console.log("inner 被点击");
// 合成事件对象对阻止事件传播;阻止原生事件和合成事件传播
ev.stopPropagation();
// 阻止原生事件,只能阻止原生事件
ev.nativeEvent.stopPropagation();
// 原生事件对象的阻止事件传播,只不过可以阻止root上绑定的方法执行
ev.nativeEvent.stopImmediatePropagation();
}}
onClickCapture={() => {
console.log("inner 被点击-onClickCapture");
}}
></div>