从零开始的react入门教程(十一),react ref 详解,三种写法与 ref 转发(传递)

壹 ❀ 引
在前面的文章中,我们介绍了react的状态提升,随之引出了redux以及context,其实都说到底都是为了方便管理react的状态,让数据交互与组件通信变得更为简单。我们知道,react属于单向数据流,属性方法都像瀑布的水往下层组件流动,子组件获取父组件的属性也很简单,一个props就能搞定。问题来了,那万一父组件需要获取子组件的属性方法?或者父组件需要直接操作子组件的DOM,这又该如何下手呢?这里就不得不提react中的refs属性,本篇文章将围绕ref用法(三种写法)以及ref转发(传递)展开,文中的例子推荐复制后运行,了解下大致运转过程总是好的,那么本文开始。
贰 ❀ Refs基本用法
在react的16.3版本引入了新的refs创建模式,如果要使用refs我们都推荐使用React.createRef或者函数回调模式,下面的例子也会使用React.createRef模式来介绍相关用法,当然对于另外两种模式(回调与字符串)后面也会介绍,以下例子还是基于create-react-app项目,所以大家可以在文中提到的对应文件进行代码修改,然后本地运行项目即可。
贰 ❀ 壹 ref + DOM
react提供了React.createRef来创建一个ref,然后将此ref属性附加到你想操作的DOM以及想获取属性方法的子组件上,我们在index.js文件中添加如下代码:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount(){
console.log(this.echoRef);
}
render() {
// 这里的ref就是必须这么写了,通过ref属性将this.echoRef与子组件关联
return <div ref={this.echoRef}>你好啊,echo。</div>
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
控制台执行npm start运行项目,我们提前在componentDidMount中输出了this.echoRef,打开控制台,可以看到输出的是一个对象,对象有个current属性,展开后发现current指向的就是我们添加了this.echoRef的div元素。所以可以得知,通过this.refName.current能访问到添加了ref属性的DOM元素或者组件。
我们修改上述componentDidMount中的输出代码为this.echoRef.current.innerHtml,打开控制台:

那么问题来了,假设我创建了一个ref,用在了多个元素上会怎么样呢?这里我们修改render内部的代码为:
render() {
return (
<Fragment>
<div ref={this.echoRef}>你好啊,echo。</div>
<div ref={this.echoRef}>你好啊,时间跳跃。</div>
</Fragment>
)
}

保存后查看控制台,你会发现只有后面div的生效了,也就说,ref的绑定就像一个同名的变量赋值,它永远以最后关联的DOM为准,一个ref只能关联一个,无法重复使用。假设需要关联多个,我们完全可以创建多个ref,这一点大家可以自行尝试。
关于上述中,我们使用了Fragment组件,在JavaScript中其实也有DocumentFragment相关概念,意思就是最小文档片段。我们知道render中只接受一个根元素作为最外层DOM,比如如下代码就会报错:
render() {
return (
<div ref={this.echoRef}>你好啊,echo。</div>
<div ref={this.echoRef}>你好啊,时间跳跃。</div>
)
}
传统做法是添加一个公有的父级div将其包裹起来,比如:
render() {
return (
<div>
<div ref={this.echoRef}>你好啊,echo。</div>
<div ref={this.echoRef}>你好啊,时间跳跃。</div>
</div>
)
}
但这样会产生一层无意义的div结构,虽然对于DOM优化来说影响微乎其微,但能少一层总是好的,我们打开控制台查看Fragment包裹的html结构,如图:

你会发现Fragment并没有产生多余的DOM结构,如果你了解过vue或者微信小程序,react的Fragment对标vue的template与小程序的block标签,题外话说到这里。
贰 ❀ 贰 ref + Class组件
前面的例子我们将ref加在了DOM上,现在我们试试加在一个子组件上,修改index.js代码为:
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount() {
console.dir(this.echoRef.current);
// 这里调用了子组件的方法
this.echoRef.current.handleClick();
}
render() {
return (
<Children ref={this.echoRef} userName="echo" />
)
}
}
class Children extends Component {
constructor(props) {
super(props);
}
state = {
userName: '听风是风'
}
// 这个方法给父组件调用
handleClick = () => { console.log('我在调用子组件的方法。') }
render() {
return (
<div>你好,我是{this.props.userName}。</div>
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);

打开控制台,你会发现当前this.echoRef.current访问到的就是我们的Children组件,而且你能看到Children上声明的state以及方法,我们通过this.echoRef.current.handleClick()调用了子组件的方法,因此控制台输出了我在调用子组件的方法。。
ref不仅仅能获取子组件的属性,同样能像链式读取那样访问到自己的孙子组件,以及更下层的组件的属性,现在我们再嵌套一层组件Grandson,如下:
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount() {
console.dir(this.echoRef.current);
// 这里调用了孙子组件的方法
this.echoRef.current.timeStepRef.current.handleClick();
}
render() {
return (
<Children ref={this.echoRef} userName="echo" />
)
}
}
class Children extends Component {
constructor(props) {
super(props);
this.timeStepRef = React.createRef();
}
state = {
userName: '听风是风'
}
// 这个方法给父组件调用
handleClick = () => { console.log('我在调用子组件的方法。') }
render() {
return (
<Grandson ref={this.timeStepRef} />
)
}
}
class Grandson extends Component {
constructor(props) {
super(props)
}
// 这个方法给祖父组件使用
handleClick = () => { console.log('我是给上上层组件使用的方法') }
render() {
return (
<div>你好,我是孙子组件。</div>
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);

如上图的对象解构,我们在父级组件通过this.echoRef.current.timeStepRef.current.handleClick();调用了孙子组件的方法,所以不管组件嵌套多少层,只有有定义ref你就一定能向下访问到你想要的属性,当然,这种做法想想就知道非常不好!
贰 ❀ 叁 ref + 函数组件以及ref转发
默认情况来说,ref不能添加在函数组件上,因为函数组件没有实例,如果你按照前面的做法代码会给出警告,比如下面这个例子:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
function Children () {
return <div>我是子组件</div>;
}
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount() {
console.dir(this.echoRef.current);
}
render() {
return (
<Children ref={this.echoRef} userName="echo" />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
Warning:Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
但是呢,我们是可以在函数组件内,为其它DOM或者组件绑定ref,比如这个例子:
import React, { createRef } from 'react';
import ReactDOM from 'react-dom';
function Children(props, ref) {
const inputRef =createRef();
const handleClick = ()=>{
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>点我让输入框聚焦</button>
</>
);
}
ReactDOM.render(
<Children />,
document.getElementById('root')
);

综合来解释,默认情况下,函数组件内部可以使用ref去绑定其它的DOM或者组件,但是如果你要直接给一个子函数组件上添加ref就会出现上面的警告,警告中也给出了解决方案,那就是使用React.forwardRef。
PS:上述代码中出现的<></>标签作用与Fragment作用相同,这个做个补充。
我们先来看看如何能在函数组件上添加ref属性而不报警告,看下面这个例子:
import React, { Component, forwardRef, useRef, useImperativeHandle, createRef } from 'react';
import ReactDOM from 'react-dom';
function Children(props, ref) {
// useRef是一个hook,你只用知道它可以创建ref
const inputRef = useRef();
// 你可以通过这种方式创建
// const inputRef = createRef()
const sayName = () => {
console.log(1);
}
useImperativeHandle(ref, () => ({
focus: () => {
// 这里操作的是input自带的focus方法
inputRef.current.focus();
}
}));
return <input ref={inputRef} />;
}
// 由于函数组件不能用ref,这里使用`forwardRef`包裹了一层
Children = forwardRef(Children);
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount() {
console.log(this.echoRef);
this.echoRef.current.focus();
}
render() {
return (
<Children ref={this.echoRef} />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
一下子出现了很多奇奇怪怪的方法,别急,我们来解释它们。现在你不用了解这些方法的原理,你只用大致知道它们做了什么,深入的学习应该在更后面,因为这里涉及到了hook的知识。
react在16.8版本新增了hook特性,准确来说,hook颠覆了我们之前Class组件以及生命周期那一套。hook中没有生命周期,所有的组件都是函数组件,很明显,函数组件内是没有this的,那自然没办法从父级组件访问函数组件this(组件实例)上的属性方法。但是假设现在我们就是要操作函数组件的DOM,比如上面的例子。
我们来解释上面的代码,首先forwardRef接受一个函数,此函数支持2个参数props与ref,props很好理解,就是上层传递下来的属性,而ref自然也是上层传递下来的ref。比较巧的是我们的Children本身就是个函数,因此我们直接使用forwardRef进行了包裹,可以理解为给组件升了个级。
而在Children内部const inputRef = useRef()这一句,也是使用hook提供的API创建一个ref,他与createRef的原理以及含义上有一定差异,不过这里我们就理解为创建了一个ref。
紧接着inputRef与函数组件内部的input相关联,也就是说现在函数组件内是可以直接使用input内置的属性方法。前面说了,函数组件自己内部还是可以使用ref的,只是我们不能直接用ref关联一个函数组件,但是前面我们通过forwardRef给函数组件升了级。
紧接着,我们通过useImperativeHandle将函数组件内部能访问到的input上的属性方法,再次暴露给了父组件,useImperativeHandle中的ref其实就是上层传递的,这里就是通过此方法,将上层ref与函数组件内部产生了关联。我们自己定义了一个focus方法,而这个方法内部执行的却是input的focus方法,组件内部可以通过inputRef.current.focus访问到input的方法(希望你没绕晕。)

于是我们在父组件中通过this.echoRef.current.focus()访问到了函数组件暴露给它的方法,而这个方法本质执行的其实是input自带的focus方法。
不知道你理解没有,这里我们通过forwardRef帮父组件做了一次转发,父组件其实想访问的就是input的方法,但是函数组件在中间隔了一层,父组件就没法直接拿到,而我们通过useImperativeHandle帮父组件代劳了一次,成功达到了目的。
其实forwardRef除了能让函数组件使用ref外,还有另一种强大的作用就是转发ref。
比如A>B>C的组件结构,你在A中创建了一个ref,你希望将这个ref作为props传递给B,然后在B中接受这个ref再去去关联C,以达到在A中可以访问到C的属性。我们可以假想有一个hoc的场景,父组件希望访问B组件,但是B组件被hoc包裹了一层,也就是一个高阶组件。此时你的ref假设绑定在了hoc生成的B,那么ref将访问hoc组件而非B组件。那么怎么让父组件可以访问到这个B组件呢?我们可以借用forwardRef:
import React, { Component, forwardRef } from 'react';
import ReactDOM from 'react-dom';
function hocComponent(Component) {
// 单纯包装了传入的组件,生成了一个新的组件,只是在生成中我们还用了forwardRef在外面包了一层
return forwardRef((props, ref) => {
return <Component {...props} ref={ref} />
})
}
class Parent extends Component {
constructor(props) {
super(props);
// 创建一个ref,这个ref随便你取什么名字
this.echoRef = React.createRef();
}
componentDidMount() {
console.log(this.echoRef);
this.echoRef.current.handleClick();
}
render() {
// 传入Children给高阶组件,得到了一个新组件
const Child = hocComponent(Children);
return (
<Child ref={this.echoRef} />
)
}
}
class Children extends Component {
constructor(props) {
super(props);
}
handleClick = () => {
console.log('给父级调用的方法')
}
render() {
return <>我是子组件啊</>;
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);

这个例子就解释了hoc的情况,这个例子相对上面参杂了hook的例子来说应该好理解一点,这里就不多解释。至少到这里,我们解释了forwardRef的两种作用,一是也可以给函数组件绑定ref,第二点就是ref转发,比如hoc包裹,我们绕过绕过高阶组件,拿到高阶组件内部真正的组件属性。
另外!!!A>B>C,假设B是函数组件,我们希望A的ref绑定C从而访问C,其实还有一种做法,就是不要直接ref绑定,而是把ref作为props传递下去后再绑定,这样不管B是不是函数组件,都能成功绑定到C,再来个例子:
import React, { Component, forwardRef } from 'react';
import ReactDOM from 'react-dom';
function Children(props) {
return (
// 子组件接受了这个ref,然后再通过ref进行绑定
<input ref={props.inputRef} />
);
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.echoRef = React.createRef();
}
componentDidMount() {
console.dir(this.echoRef.current);
}
handleClick = () => {
// 成功访问了子组件下的子组件
this.echoRef.current.focus();
}
render() {
return (
<>
<Children
inputRef={this.echoRef}//我们希望把这个ref作为props传递下去
/>
<button onClick={this.handleClick}>点我聚焦</button>
</>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
因为给函数组件上添加ref会警告,那么我们就不用ref,而是把创建的ref作为属性传下去,在子组件中接受后,再绑定给你要访问的DOM或者组件,这样不仅解决了函数组件绑定ref的问题,还搞定了ref转发的问题,一箭双雕。
叁 ❀ 回调模式与字符串模式
上面我们介绍了createRef创建ref的模式,接下来补充函数回调模式与字符串模式,因为用法介绍的比较多了,这里只是介绍写法。
叁 ❀ 壹 回调模式
在第二小节中,我们通过createRef()模式介绍了ref的基本用法与部分使用场景,其实react还支持函数回调的形式来绑定ref,这种模式下不需要借用createRef创建一个ref,而是直接将需要绑定的DOM或者组件传递到函数中进行关联,直接看个例子:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Children extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.inputRef);
}
setRef = (e) => {
this.inputRef = e;
}
// 此方法暴露给父组件
inputFocus = () => {
this.inputRef.focus();
}
render() {
return <input ref={this.setRef} />;
}
}
class Parent extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.echoRef);
// 拿到子组件内定义的方法
this.echoRef.inputFocus();
}
// 定义绑定ref函数
setRef = (e) => {
this.echoRef = e;
}
render() {
return (
// 这里不再直接绑定ref,而是上述函数
<Children ref={this.setRef} />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
在上述代码中我们并没使用API创建ref,而是直接定义了一个函数,此函数接受的参数其实就是你所绑定此方法的DOM或者组件,比如在父组件中,我们通过ref={this.setRef}将Children与父组件中的this.echoRef进行了绑定。而在子组件中,我们同样通过此方法绑定了input,最终我们在父组件中通过this.echoRef.inputFocus间接调用了input的方法。
在父子组件的componentDidMount中我们添加了输出信息,打开控制台可以看到父组件成功访问到了子组件,而子组件成功访问到它所绑定的input。

上述代码中,我们还是通过ref={callback}的形式进行子组件绑定,另外callback也能作为props传递后,再在子组件中进行绑定,比如:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Children extends Component {
constructor(props) {
super(props);
// 子组件接受传递的回调进行绑定
props.setRef(this);
}
componentDidMount() {
console.dir(this.inputRef);
}
setRef = (e) => {
this.inputRef = e;
}
// 此方法暴露给父组件
inputFocus = () => {
this.inputRef.focus();
}
render() {
return <input ref={this.setRef} />;
}
}
class Parent extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.echoRef);
// 拿到子组件内定义的方法
this.echoRef.inputFocus();
}
// 定义绑定ref函数
setRef = (e) => {
this.echoRef = e;
}
render() {
return (
// 这里直接把回调传递下去了
<Children setRef={this.setRef} />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
在子组件的constructor中我们通过props.setRef(this)这一句,拿到父组件传递的callback然后绑定了当前实例,从而达到目的。还记得前面提到的A>B>C场景吗,回调模式也能这么玩,再来个例子:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Children extends Component {
constructor(props) {
super(props);
}
render() {
// 父级传递来的props,最后给了input用了
return <input ref={this.props.setRef} />;
}
}
class Parent extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.echoRef);
// 拿到子组件内定义的方法
this.echoRef.focus();
}
// 定义绑定ref函数
setRef = (e) => {
this.echoRef = e;
}
render() {
return (
// 这里直接把回调传递下去了
<Children setRef={this.setRef} />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
关于回调模式就说到这里,我们最后来说下字符串模式。
叁 ❀ 贰 字符串模式
由于字符串模式在react官方文档中已明确废弃,未来可能会移除,所以这里只给一个例子,在日常开发中不推荐这种做法进行ref绑定:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Children extends Component {
sayName=()=>{}
render() {
return <input />;
}
}
class Parent extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.refs);
// 拿到子组件内定义的方法
// this.echoRef.focus();
}
render() {
return (
// 这里直接把回调传递下去了
<>
<Children ref='echoRef' />
<input ref='timeRef' />
</>
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);

在上述代码中,我们通过ref='refName'的形式为DOM或者组件绑定ref,同样,我们可以通过this.refs.refName拿到对应绑定的组件,其实看到refs这个负数,你就应该可以猜到它能访问当前组件实例中的所有ref,上面的例子也验证了这一点,关于字符串形式就聊这么多。
肆 ❀ 总
OK,让我们回顾本文所提到的知识点,介绍了三种ref方式,React.createRef,函数回调以及字符串模式,当然我们不推荐字符串,因为它已被官方废弃。
函数组件不支持为其添加ref属性,因为函数组件没有实例,但我们提到可以通过forwardRef对于函数组件进行包裹,毕竟对于hook而言,组件都是函数组件,react也是提供了此做法来解决ref获取的问题。
我们介绍了A>B>C的组件嵌套场景,如何将A中定义的ref转发给C绑定了,除了forwardRef做法外,我们知道ref也能定义好后,作为props向下传递。
另外,我们在通过ref获取子组件属性时,比如获取一个函数,请注意函数的写法,比如这个例子中,我们能拿到sayName,但拿不到sayAge,这是因为后者本质上是绑定在原型上,无法通过这种方式直接访问,但是你可以通过原型找到它。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Children extends Component {
constructor(props) {
super(props);
}
sayName = () => { }
sayAge() { }
render() {
// 父级传递来的props,最后给了input用了
return <input />;
}
}
class Parent extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.dir(this.echoRef);
}
// 定义绑定ref函数
setRef = (e) => {
this.echoRef = e;
}
render() {
return (
// 这里直接把回调传递下去了
<Children ref={this.setRef} />
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);

要介绍的大概就这么多了,那么本文结束。
伍 ❀ 参考
从零开始的react入门教程(十一),react ref 详解,三种写法与 ref 转发(传递)的更多相关文章
- react router @4 和 vue路由 详解(三)react如何在路由里面定义一个子路由
完整版:https://www.cnblogs.com/yangyangxxb/p/10066650.html 5.react如何在路由里面定义一个子路由? a.引入在需要子路由的页面引入Rout ...
- gitbook 入门教程之常用命令详解
不论是 gitbook-cli 命令行还是 gitbook editor 编辑器都离不开 gitbook 命令的操作使用,所以再次了解下常用命令. 注意 gitbook-cli 是 gitbook 的 ...
- Mac OS 10.15系统入门教程 系统语言输入法详解
对于一些Mac新手来说呢还不知道偏好设置到底是什么?有什么用处?其实Mac系统内的几乎所有的系统相关的设置都会在系统偏好设置内出现. 切换系统语⾔在语言与地区设置中拖拽左侧的语言条目就可以切换系统的语 ...
- Shell入门教程:Shell函数详解
Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快. 1.函数定义 ...
- git入门教程,主要命令详解。
准备工作 git clone url / ssh ----------------------------------------------------------------------从git ...
- AngularJS入门教程之数据绑定原理详解
这篇文章主要是写给新手的,是给那些刚刚开始接触Angular,并且想了解数据帮定是如何工作的人.如果你已经对Angular比较了解了,那强烈建议你直接去阅读源代码. Angular用户都想知道数据绑定 ...
- react 入门教程 阮一峰老师真的是榜样
- 转自阮一峰老师博客 React 入门实例教程 作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Nati ...
- React入门教程(二)
前言 距离上次我写 React 入门教程已经快2个月了,年头年尾总是比较忙哈,在React 入门教程(一)我大概介绍了 React 的使用和一些注意事项,这次让我们来继续学习 React 一. Rea ...
- React入门教程1---初见面
React入门教程1---初见面:https://blog.csdn.net/solar_lan/article/details/82799248 React 教程 React 是一个用于构建用户界面 ...
- 无废话ExtJs 入门教程十一[下拉列表:Combobox]
无废话ExtJs 入门教程十一[下拉列表:Combobox] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个一个下拉列表: 1.代码如下: 1 <!DOCT ...
随机推荐
- java进阶(20)--final/fianlly/fianlize区别
1.final关键字.表示最终的.不变的 final修饰的类无法继承 final修饰的方法无法覆盖 final修饰的变量不能重新赋值 举例: final double weight; 2.finall ...
- printf 函数格式控制
Printf()介绍 printf()是C语言标准库函数,用于将格式化后的字符串输出到标准输出.标准输出,即标准输出文件,对应终端的屏幕.printf()申明于头文件stdio.h. 函数原型: in ...
- Mybatis @Insert插入数据返回自增的主键id
mapper层 @Insert("insert into t_user (username,password,valid,create_time) values (#{username},# ...
- 让vs支持wsl调试
WSL安装 wsl --install -d Ubuntu 等一会提示输入用户名,不用管它,直接关闭,下次打开wsl,会以无密码的root用户打开 wsl卸载 wsl --unregister Ubu ...
- Python Code_02
author : 写bug的盼盼 development time : 2021/8/27 19:59 变量定义 name = '阿哈' print(name) print('标识',id(name) ...
- [转帖]Linux 内核的 4 大 IO 调度算法
https://cloud.tencent.com/developer/article/1615744 Linux 内核包含4个IO调度器,分别是 Noop IO scheduler.Anticipa ...
- [转帖]AMD Zen CPU 架构以及不同CPU性能大PK
https://plantegg.github.io/2021/08/13/AMD_Zen_CPU%E6%9E%B6%E6%9E%84/ 前言 本文先介绍AMD Zen 架构,结合前一篇文章<C ...
- [转帖]MegaRaidCli64 常用命令解释
MegaRaidCli64 常用命令解释 安装 查看 创建 删除 案例 安装 Centos wget https://docs.broadcom.com/docs-and-downloads/raid ...
- [转帖]enq: TX - row lock contention故障处理一则
https://www.cnblogs.com/zhchoutai/p/7088826.html 一个非常easy的问题,之所以让我对这个问题进行总结.一是由于没我想象的简单,在处理的过程中遇到了 ...
- CPU实际频率查看
cat /sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq