React系列(八)——React进阶知识点拓展

前言

在之前的学习中,我们已经知道了React组件的定义和使用,路由配置,组件通信等其他方法的React知识点,那么本篇文章将针对React的一些进阶知识点以及React16.8之后的一些新特性进行讲解。希望对各位有所帮助。


一、setState
(一)更新状态的2种写法

在之前更新state的时候,我们常常使用的是this.setState()方法进行状态的更新,传入的参数是一个{key:value}对象,用于对state中指定的值进行更新。比如下面更新count值的写法:

import React, { Component } from 'react'
export default class Demo extends Component {state = {count:0}increment = ()=>{const {count} = this.state;this.setState({count:count+1}}render() {return (<div>当前的数值为: {this.state.count}<br/><button onClick={this.increment}>点我+1</button></div>)}
}

上面的写法固然不错,但实际上setState函数传入的参数不仅可以是一个对象,还可以是一个函数,在函数中我们可以接收到入参state,然后直接进行状态的更新。我们之前之间传入一个对象,其实可以看成是这种函数写法的简写方式。

export default class Demo extends Component {state = {count:0}increment = ()=>{this.setState(state=>({count:state.count+1}));}render() {return (<div>当前的数值为: {this.state.count}<br/><button onClick={this.increment}>点我+1</button></div>)}
}

值得一提的是,虽然这种写法自带的state可以方便我们后续操作,但实际上我们还是用的比较少,毕竟直接传入对象相对来说更加简单~

(二)指定setState的回调函数

setState函数除了可以传入要更新的状态之外, 还可以接收第二个参数,更新完状态后的回调函数。我们可以先看下面这个案例:

export default class Demo extends Component {state = {count:0}increment = ()=>{this.setState(state=>({count:state.count+1}));console.log(this.state.count)}render() {return (<div>当前的数值为: {this.state.count}<br/><button onClick={this.increment}>点我+1</button></div>)}
}

按道理说,当点击按钮时,会对count的值进行+1操作,并打印出更新完状态的最新值,但实际的结果是:

setState演示用例

我们可以看到,此时打印的结果却是count未更新前的值,原因是setState()虽然是同步方法,但具体更新状态的方法却是异步的,如果想要更新最新状态值做某些操作的话,就需要我们把对应的操作放在回调函数中。

export default class Demo extends Component {state = {count:0}increment = ()=>{this.setState(state=>({count:state.count+1}),()=>{console.log(this.state.count)});}render() {return (<div>当前的数值为: {this.state.count}<br/><button onClick={this.increment}>点我+1</button></div>)}
}

使用回调函数之后,我们可以看到,打印的结果就是我们想要的了:


setState演示用例2
二、懒加载:lazyLoad

实际上当页面导航栏的对应着多个组件时,即使用户只需要使用其中的1个或者几个,但页面在加载的时候还是会将所有组件都加载出来,这其实是不太合理的。组件的懒加载就可以帮助我们解决这个问题。
同时,懒加载需要配合Suspense 一起使用。这样做的原因很简单:一次性把组件加载出来,虽然一开始全部加载的时候速度会比较慢,但后面打开的速度就会很快。而懒加载的话,由于还要再发一次网络请求,所以react会要求我们在等待结果返回的过程中,定义一个类似于Loading提示的组件,以此来提高用户体验(否则用户看到的将是白屏)

未使用懒加载之前,如上述所说,页面就可以把对应的组件都加载好了(我们可以直接在main.chunk.js文件中找到对应组件的代码):

懒加载演示用例1

而实际上,React本身就提供了lazy函数供我们对组件进行懒加载配置:

步骤1: 引入 lazy函数和Susqense组件
import React, { Component,lazy,Suspense} from 'react'
步骤2:使用lazy函数,把需要懒加载的组件作为参数传入
const About = lazy(()=>import('./About'))
const Home = lazy(()=>import('./Home'))
步骤三:使用Suspense组件,对路由进行包裹
 <Suspense><Route path="/about" component={About} /><Route path="/home" component={Home} />
</Suspense>
步骤四:定义Loading组件

在开头我们就解释过,使用懒加载的话只有当每次用户点击后,才会真正发起获取组件的网路请求,Loading组件存在的意义就是在请求的响应回来之前,页面上先显示Loading组件,不让页面出现白屏的效果。

import React, { Component } from 'react'export default class Loading extends Component {render() {return (<div><h1 style={{backgroundColor: "gray",color:'orange'}}>Loading...</h1></div>)}
}
步骤五:引入组件并将Loading组件作为回调传入Suspense组件中:
 <Suspense fallback={<Loading/>}><Route path="/about" component={About} /><Route path="/home" component={Home} />
</Suspense>
最终,我们可以在浏览器的控制台上查看效果:

lazyLoading演示用例2

当使用懒加载之后,只有当我们点击的时候,才会发起新的请求,这里的 0.chunk.js就是请求回来的结果,如果我们点进去看的话,就可以在其中发现我们的组件代码了。

三、Fragment标签的使用

我们知道,使用JSX语法定义组件时,会要求我们返回唯一一个根标签,但是这样有一个缺点:让我们的页面嵌套层次过深,我们可以使用 Fragment 或者 <></> 这种空标签来避免上述问题。需要注意的是,虽然二者都可以解决根标签的问题,但是在使用上二者还是有些不同的,Fragment标签中可以传递参数key,而空标签是不允许传递参数的。
我们可以看看未使用Fragment标签时,页面上的元素:

App组件
export default class App extends Component {render() {return (<div><Demo/></div>)}
}
Demo组件
export default class Demo extends Component {render() {return (<div><input /><br /><input /></div>)}
}
Fragment演示用例1

我们可以看到,虽然页面上的元素正常显示,但还是会嵌套在不需要使用到的div标签中,我们可以使用Fragment标签或者空标签来解决这个问题:

App组件:
import React, { Component,Fragment } from 'react'
import Demo from './4_fragement'export default class App extends Component {render() {return (<Fragment><Demo/></Fragment>)}
}
Demo组件
import React, { Component, Fragment } from 'react'export default class Demo extends Component {render() {return (<><input /><br /><input /></>)}
}
Fragment演示用例2

我们可以看到,使用<Fragment>或者使用<></>标签都有着使组件不需要有一个真实DOM标签的功能,但实际上二者在使用上还是略有不同的,Fragment标签可以接收key属性的参数,而空标签是不可以接收属性参数的。

四、实例对象Context属性的应用

我们知道,使用props属性自然可以将方法或者数据从父组件上逐层传递到子组件中。但是当组件间的嵌套关系比较深的时候,这时再通过props来传递值就会很麻烦,针对这种情况,我们可以考虑用Context来解决这个问题:Context其实是组件实例对象上的一个属性,利用ProviderConsumer,我们可以实现值的传递。
假如目前有A、B、C三个组件,B是A的子组件,C是B的子组件:

export default class A extends Component {state = { name: '小明', age: 18 }render() {const {name,age} = this.state;return (<div className="parent">我是A组件<br /><h4>姓名是:{this.state.name},年龄是:{this.state.age}</h4><B /></div>)}
}
class B extends Component {render() {return (<div className="child">我是B组件<C /></div>)}
}
class C extends Component {render() {return (<div className="grand">我是C组件<h4>从A组件获取到的值为</h4></div>)}
}

如果C组件想要获取A组件的值,我们可以通过以下步骤来实现:

步骤1:通过React.createContext(),获取ProviderConsumer
const MyContext = React.createContext();
const { Provider, Consumer } = MyContext;
步骤2:在A组件中使用Provider包裹住子组件
export default class A extends Component {state = { name: '小明', age: 18 }render() {const {name,age} = this.state;return (<div className="parent">我是A组件<br /><h4>姓名是:{this.state.name},年龄是:{this.state.age}</h4>{/* 使用Provider包裹住子组件,有需要的后代组件通过Consumer标签即可获取,需要注意,value传入的值是一个对象 */}<Provider value={{name,age}}><B /></Provider></div>)}
}
步骤3:在C组件中通过Consumer标签获取A组件的值
class C extends Component {render() {return (<div className="grand">我是C组件<h4>从A组件获取到的值为<Consumer>{value => `姓名为:${value.name},年龄为:${value.age}`}</Consumer></h4></div>)}
}
五、PureComponent的使用

对于子组件来说,一旦父组件重新render,那么其也会跟着一起重新执行一次render方法,即使子组件并没有使用到父组件传递的任何属性。或者当父组件空调用一次setState方法,那么此时state并没有真的改变,但是子组件还是要重新执行一次render,这其实是不太合理的。

export default class Parent extends Component {state = {carName:'哈雷摩托',stus:['小明','小红']}changeCar = ()=>{//this.setState({carName:'特斯拉'})this.setState({})}addStus = ()=>{this.setState({stus:['小明',...this.state.stus]})}render() {console.log('父组件的render方法调用了')const {carName,stus} = this.state;return (<div className="parent"><h3>父组件的车名为:{carName}</h3><h4>{stus}<button onClick={this.addStus}>点我加人</button></h4><button style={{marginBottom: '5px'}} onClick={this.changeCar}>点击换车</button><Child carName={carName}></Child></div>)}
}
class Child extends Component {render() {console.log('子组件的render方法调用了')return (<div className="child"><h4>接收到父组件的车名为:{this.props.carName}</h4></div>)}
}
pureComponent演示用例1

解决这个问题的方法有2个:

(1)手动写 componentShouldUpdate方法,对状态是否改变进行判断

比如我们可以通过下面这个钩子来避免组件发生无效的render:

    shouldComponentUpdate(nextProps,nextState){return nextState.carName !== this.state.carName }
(2)利用PureComponent组件,里面帮我们重写了shouldComponentUpdate方法

我们可以利用组件内componentShouldUpdate这个钩子,来根据实际需要判断是否执行render,但如果说状态比较多,就需要我们手动写很多判断条件,比较麻烦。我们更加常用的是直接继承和使用PureComponent组件。

import React, { Component,PureComponent } from 'react'
import './index.css'export default class Parent extends PureComponent {
...
}class Child extends PureComponent {...
}
pureComponent案例演示2
六、render props属性的应用

对于关系明确的父子组件来说,我们可以比较简单的从组件的嵌套关系来判断组件间的父子关系。但是有时候我们可能并不能确定父组件中的子组件具体是哪一个,而是等到具体调用的时候才知道。
比如说有A、B、C三个组件,且我们知道A是B的父组件,B是C的父组件,那么对应的代码为:

export default class A extends Component {render() {return (<div className="parent"><B/></div>)}
}class B extends Component {render() {return (<div className="parent"><C/></div>)}
}class C extends Component {render() {return (<div className="parent"></div>)}
}

但有时候我们可能只知道B组件内需要传递一个组件,但具体是哪个组件却不能确定,只能等到具体使用的时候才能确定,这个时候就需要用props的方法来解决了。
Vue中,这种问题的解决方案被称为插槽技术
React中,我们通常使用children props以及render props属性来解决这类问题。其中,children props虽然可以完成组件的传递,但是却不能实现父子组件的数据传递而render props则可以解决这类问题

export default class A extends Component {render() {return (<div className="parent"><B><C/></B></div>)}
}class B extends Component {render() {return (<div className="parent">{this.props.children}</div>)}
}class C extends Component {render() {return (<div className="parent"></div>)}
}

用上面这种方式,我们可以通过 通过组件标签体的方式传入组件,在对应的组件内使用{this.props.children}进行展示。这样就使得组件的灵活性大大提高,但这种方式的缺点也很明显,C组件虽然是B组件的子组件,但是却不能获取B组件的值。这时,就需要用到第二种方式:使用render props进行参数的传递。

export default class A extends Component {render() {return (<div className="parent"><B render={name => <C name={name} />}/></div>)}
}class B extends Component {state = {name:'小明'}render() {return (<div className="parent">{this.props.render(name)}</div>)}
}class C extends Component {render() {return (<div className="parent"><h4>接收到的父组件参数是: {this.props.name}</h4></div>)}
}

通过上述这种方式,我们就可以把父组件的参数传递给子组件了,需要注意的是本质上这里使用的还是组件的props属性,所以props不一定名字要叫render,只是很多时候我们约定俗成地将这种传递值的方式的props值设为render

七、错误边界:ErrorBoundary

当子组件发生错误时,我们会希望子组件的错误不影响到父组件其他功能的使用,这时候我们就可以在父组件上设置错误边界,来防止由于子组件错误而影响到整个页面不能使用的情况出现。解决方法是利用react的一个生命周期 getDerivedStateFromError
我们先来看一下案例,现在存在有Parent组件和Child组件:

Parent组件:
export default class Parent extends Component {state = {hasError:''}static getDerivedStateFromError(err){return {hasError: err}}render() {return (<div><h2>我是父组件</h2><Child/></div>)}
}
Child组件:
export default class Child extends Component {state = {person:[{name:'小明',age:10},{name:'大明',age:31},{name:'小红',age:16},]}render() {return (<div><h2>我是子组件</h2>{this.state.person.map(ele=>{return <li>{ele.name}--{ele.age}</li>})}</div>)}
}

页面上显示的效果如下:


errorBoundary演示用例1

组件中state的数据往往是通过请求后台返回回来的,如果说后台发生意外,传来的数据格式有问题,如果没有合理的解决这个问题,页面可能就直接用不了了。

export default class Child extends Component {state = {person: 'hh'}render() {return (<div><h2>我是子组件</h2>{this.state.person.map(ele=>{return <li>{ele.name}--{ele.age}</li>})}</div>)}
}
errorBoundary演示用例2

由于返回的数据有问题,使得原先的代码逻辑判断发生了错误,遇到这种情况,我们会希望把错误缩小到当前组件上,而不会对父组件以及其他组件的使用造成干扰。这时,我们就可以使用 getDerivedStateFromError来对子组件的错误进行捕获和限制。

给父组件加上钩子
export default class Parent extends Component {state = {hasError:''}static getDerivedStateFromError(err){return {hasError: err}}render() {return (<div><h2>我是父组件</h2>{this.state.hasError ? '网络不通畅,请稍后再试...':<Child/>}</div>)}
}

getDerivedStateFromError会捕获到子组件传递的错误,我们可以利用这个特性,对组件的显示进行判断。
需要注意的是,要想更好的观察错误边界这个效果,最好是打包后在服务器上面看效果。(在开发模式下,错误边界不起作用)。

errorBoundary演示用例3

我们可以看到,此时虽然子组件发生错误,但还是不影响页面的正常使用。另外,错误边界只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误。

八、Hook

我们知道,函数式组件由于无法使用this,所以也就不能像类式组件一样使用state和ref等属性。但是在React16.8 之后,官方推出了3个hook,使得函数式组件也可以像类式组件一般使用对应的属性以及常用的生命周期函数:

(1). State Hook: React.useState(): 可以使用state
(2). Effect Hook: React.useEffect(): 可以模拟生命周期钩子
(3). Ref Hook: React.useRef(): 可以使用ref
(一)State Hook 钩子
export default function Demo() {function add(){}return (<div><h2>当前总和为:???</h2><button onClick={add}>点我+1</button></div>)
}

我们想要赋予给函数式组件Demo一个state属性count,此时我们就可以这样实现:
使用React.useState()方法,我们可以传入对应属性的初始值,方法会返回一个数组,第一个参数是当前属性的值,第二个参数是修改这个属性的方法,我们可以在后续使用的时候,具体来设置方法的逻辑。

export default function Demo() {const [count,setCount] = React.useState(0);function add(){// setCount(count+1);  setCount的第一种写法setCount(count => count+1)}return (<div><h2>当前总和为:???</h2><button onClick={add}>点我+1</button></div>)
}
(二)Effect Hook

Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)。Effect Hook算是三个Hook之中较为复杂的一个了,我们可以用它来模拟componentDidMountcomponentDidUpdatecomponentWillUnmount这三个生命周期函数。
我们现在在上个案例的基础上再新增一个功能:每隔1秒钟,将count的值进行+1,如果是放在类式组件中,我们很容易就会想到使用componentDidMount来调用一个定时器,但是在函数式组件中,由于没有生命周期钩子函数,所以我们需要用React.useEffect()来实现我们的代码。

export default function Demo() {const [count,setCount] = React.useState(0);// 使用 Ref Hook,用法和React.createRef()一样const myRef = React.useRef();React.useEffect(()=>{let timer = setInterval(()=>{setCount(count => count+1);},1000)},[])function add() {// setCount(count+1);  setCount的第一种写法setCount(count => count+1)}return (<div><input type="text" ref={myRef}/><h2>当前总和为:{count}</h2><button onClick={add}>点我+1</button></div>)
}

userEffect需要传入2个参数,第一个相当于是组件加载好后执行的函数,第二个是指定具体监测的state
当第二个参数为空数组时,表示不监测任何一个state,即组件只加载一次,相当于是 componentDidMount钩子, 当第二个参数传入真实的state时,那么一旦监测的state状态发生改变,那么第一个函数就会调用,此时相当于是componentDidUpdate钩子 。同时,useEffect的return需要传入一个方法,在组件销毁的时候调用,相当于是 componentWillUnmount钩子。
我们现在再新增一个需求,利用useEffect的return方法,在卸载组件后停止运行定时器:

export default function Demo() {const [count,setCount] = React.useState(0);// 使用 Ref Hook,用法和React.createRef()一样const myRef = React.useRef();React.useEffect(()=>{let timer = setInterval(()=>{setCount(count => count+1);},1000)return ()=>{clearInterval(timer)}},[])function add() {// setCount(count+1);  setCount的第一种写法setCount(count => count+1)}function unmount(){ReactDOM.unmountComponentAtNode(document.getElementById('root'));}return (<div><input type="text" ref={myRef}/><h2>当前总和为:{count}</h2><button onClick={add}>点我+1</button><button onClick={unmount}>点击卸载组件</button></div>)
}

实际上,在点击卸载组件的按钮时,就会触发useEffect函数中return中定义的函数,成功停止计时器。

(三)Ref Hook

Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据,其实也就是赋予函数式组件使用类似于ref属性的功能。在上面的案例的基础上,我们在添加一个需求,新增一个文本框和按钮,当点击按钮时,把文本框的内容进行弹框显示:

    const [count,setCount] = React.useState(0);// 使用 Ref Hook,用法和React.createRef()一样const myRef = React.useRef();function add() {// setCount(count+1);  setCount的第一种写法setCount(count => count+1)}function show(){alert(myRef.current.value);}return (<div><input type="text" ref={myRef}/><h2>当前总和为:{count}</h2><button onClick={add}>点我+1</button><button onClick={show}>点击提示文本框内容</button><br/></div>)
}
说在最后:

本篇文章的代码已经放在了码云上,有需要的可以通过下面的链接下载:
https://gitee.com/moutory/react-extension

最后编辑于:2024-12-10 21:53:25


喜欢的朋友记得点赞、收藏、关注哦!!!

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

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

相关文章

PCIe_Host驱动分析_地址映射

往期内容 本文章相关专栏往期内容&#xff0c;PCI/PCIe子系统专栏&#xff1a; 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入 深入解析非桥PCI设备的访问和配置方法 PCI桥设备的访问方法、软件角度讲解PCIe设备的硬件结构 深入解析PCIe设备事务层与配置过程 PCIe的三…

【阅读记录-章节6】Build a Large Language Model (From Scratch)

文章目录 6. Fine-tuning for classification6.1 Different categories of fine-tuning6.2 Preparing the dataset第一步&#xff1a;下载并解压数据集第二步&#xff1a;检查类别标签分布第三步&#xff1a;创建平衡数据集第四步&#xff1a;数据集拆分 6.3 Creating data loa…

梳理你的思路(从OOP到架构设计)_简介设计模式

目录 1、 模式(Pattern) 是较大的结构​编辑 2、 结构形式愈大 通用性愈小​编辑 3、 从EIT造形 组合出设计模式 1、 模式(Pattern) 是较大的结构 组合与创新 達芬奇說&#xff1a;簡單是複雜的終極形式 (Simplicity is the ultimate form of sophistication) —Leonardo d…

【libuv】Fargo信令2:【深入】client为什么收不到服务端响应的ack消息

客户端处理server的ack回复,判断链接连接建立 【Fargo】28:字节序列【libuv】Fargo信令1:client发connect消息给到server客户端启动后理解监听read消息 但是,这个代码似乎没有触发ack消息的接收: // 客户端初始化 void start_client(uv_loop_t

Python-基于Pygame的小游戏(贪吃蛇)(一)

前言:贪吃蛇是一款经典的电子游戏&#xff0c;最早可以追溯到1976年的街机游戏Blockade。随着诺基亚手机的普及&#xff0c;贪吃蛇游戏在1990年代变得广为人知。它是一款休闲益智类游戏&#xff0c;适合所有年龄段的玩家&#xff0c;其最初为单机模式&#xff0c;后来随着技术发…

使用k6进行MongoDB负载测试

1.安装环境 安装xk6-mongo扩展 ./xk6 build --with github.com/itsparser/xk6-mongo 2.安装MongoDB 参考Docker安装MongoDB服务-CSDN博客 连接成功后新建test数据库和sample集合 3.编写脚本 test_mongo.js import xk6_mongo from k6/x/mongo;const client xk6_mongo.new…

2024 年最新前端ES-Module模块化、webpack打包工具详细教程(更新中)

模块化概述 什么是模块&#xff1f;模块是一个封装了特定功能的代码块&#xff0c;可以独立开发、测试和维护。模块通过导出&#xff08;export&#xff09;和导入&#xff08;import&#xff09;与其他模块通信&#xff0c;保持内部细节的封装。 前端 JavaScript 模块化是指…

最小堆及添加元素操作

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 最小堆及添加元素操作 [太阳]选择题 以下代码执行的结果为&#xff1f; import heapq heap [] heapq.heappush(heap, 5) heapq.heappush(heap, 3) heapq.heappush(heap, 2) heapq.…

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备&#xff0c;转发器、网桥、路由器和网关有何区别&#xff1f; (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

前端工程化-Vue脚手架安装

在现代前端开发中&#xff0c;Vue.js已成为一个流行的框架&#xff0c;而Vue CLI&#xff08;脚手架&#xff09;则为开发者提供了一个方便的工具&#xff0c;用于快速创建和管理Vue项目。本文将详细介绍如何安装Vue脚手架&#xff0c;创建新项目以及常见问题的解决方法。 什么…

罗德与施瓦茨ZN-Z129E网络分析仪校准套件具体参数

罗德与施瓦茨ZN-Z129E网络校准件ZN-Z129E网络分析仪校准套件 1&#xff0c;频率范围从9kHz到4GHz&#xff08;ZNB4&#xff09;,8.5GHz(ZNB8)&#xff0c;20GHz(ZNB20)&#xff0c;40GHz(ZNB40) 2&#xff0c;动态范围宽&#xff0c;高达140 dB 3&#xff0c;扫描时间短达4ms…

如何为IntelliJ IDEA配置JVM参数

在使用IntelliJ IDEA进行Java开发时&#xff0c;合理配置JVM参数对于优化项目性能和资源管理至关重要。IntelliJ IDEA提供了两种方便的方式来设置JVM参数&#xff0c;以确保你的应用程序能够在最佳状态下运行。本文将详细介绍这两种方法&#xff1a;通过工具栏编辑配置和通过服…

unity is running as administrator 管理员权限问题

每次打开工程弹出unity is running as administrator的窗口 unity版本2022.3.34f1&#xff0c;电脑系统是win 11系统解决方法一&#xff1a;解决方法二&#xff1a; unity版本2022.3.34f1&#xff0c;电脑系统是win 11系统 每次打开工程都会出现unity is running as administr…

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiGRU-Attention卷积神经网络结合双向门控循环单元融合注意力机制多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效…

OneCode:开启高效编程新时代——企业定制出码手册

一、概述 OneCode 的 DSM&#xff08;领域特定建模&#xff09;出码模块是一个强大的工具&#xff0c;它支持多种建模方式&#xff0c;并具有强大的模型转换与集成能力&#xff0c;能够提升开发效率和代码质量&#xff0c;同时方便团队协作与知识传承&#xff0c;还具备方便的仿…

远程控制软件新趋势

随着数字化浪潮的推进&#xff0c;远程控制软件已经成为我们生活中的一部分&#xff0c;它们不仅改变了我们的工作方式&#xff0c;还为日常生活带来了极大的便利。现在&#xff0c;让我们来探讨远程控制软件在数字时代的发展和应用&#xff0c;以及它们如何引领新的办公趋势。…

初学stm32 --- 时钟配置

目录 stm32时钟系统 时钟源 &#xff08;1&#xff09; 2 个外部时钟源&#xff1a; &#xff08;2&#xff09;2 个内部时钟源&#xff1a; 锁相环 PLL PLLXTPRE&#xff1a; HSE 分频器作为 PLL 输入 (HSE divider for PLL entry) PLLSRC&#xff1a; PLL 输入时钟源 (PL…

【Java基础面试题025】什么是Java的Integer缓存池?

回答重点 Java的Integer缓存池&#xff08;Integer Cache&#xff09;是为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围&#xff0c;因此缓存这些对象可以减少内存分配和垃圾回收的负担&#xff0c;提升性能 在 -128到127范围内的Integer对象会…

[spring]XML配置文件标签

spring的XML配置文件的标签大体可以分为两种&#xff1a; 其中的默认标签&#xff0c;我们前面文章里面出现的标签都是默认标签&#xff0c;是spring本身自带的&#xff0c;不需要我们去引入其他东西。而自定义标签则是指非默认标签的其他的由我们或产品发行方自定义的对接spir…

简单的bytebuddy学习笔记

简单的bytebuddy学习笔记 此笔记对应b站bytebuddy学习视频进行整理&#xff0c;此为视频地址&#xff0c;此处为具体的练习代码地址 一、简介 ByteBuddy是基于ASM (ow2.io)实现的字节码操作类库。比起ASM&#xff0c;ByteBuddy的API更加简单易用。开发者无需了解class file …