react render相关 【类组件、函数组件 】
[类组件] 大概就是如果是class的写法,并且extends React.component 就要手动写render
[函数组件] 如果是const App = ()=> {} 那么就酸函数组件,一般就return就可以了,已经指的自己了。
一、原理
首先,render
函数在react
中有两种形式:
在类组件中,指的是render
方法:
class Foo extends React.Component {render() {return <h1> Foo </h1>;}
}
在函数组件中,指的是函数组件本身:
function Foo() {return <h1> Foo </h1>;
}
在render
中,我们会编写jsx
,jsx
通过babel
编译后就会转化成我们熟悉的js
格式,如下:
return (<div className='cn'><Header> hello </Header><div> start </div>Right Reserve</div>
)
babel
编译后:
return (React.createElement('div',{className : 'cn'},React.createElement(Header,null,'hello'),React.createElement('div',null,'start'),'Right Reserve')
)
从名字上来看,createElement
方法用来元素的
在react
中,这个元素就是虚拟DOM
树的节点,接收三个参数:
type:标签
attributes:标签属性,若无则为null
children:标签的子节点
这些虚拟DOM
树最终会渲染成真实DOM
在render
过程中,React
将新调用的 render
函数返回的树与旧版本的树进行比较,这一步是决定如何更新 DOM
的必要步骤,然后进行 diff
比较,更新 DOM
树
# 二、触发时机
render
的执行时机主要分成了两部分:
- 类组件调用 setState 修改状态
class Foo extends React.Component {state = { count: 0 };increment = () => {const { count } = this.state;const newCount = count < 10 ? count + 1 : count;this.setState({ count: newCount });};render() {const { count } = this.state;console.log("Foo render");return (<div><h1> {count} </h1><button onClick={this.increment}>Increment</button></div>);}
}
点击按钮,则调用setState
方法,无论count
发生变化辩护,控制台都会输出Foo render
,证明render
执行了
- 函数组件通过
useState hook
修改状态
function Foo() {const [count, setCount] = useState(0);function increment() {const newCount = count < 10 ? count + 1 : count;setCount(newCount);}console.log("Foo render");return (<div><h1> {count} </h1><button onClick={increment}>Increment</button></div>);
}
函数组件通过useState
这种形式更新数据,当数组的值不发生改变了,就不会触发render
- 类组件重新渲染
class App extends React.Component {state = { name: "App" };render() {return (<div className="App"><Foo /><button onClick={() => this.setState({ name: "App" })}>Change name</button></div>);}
}function Foo() {console.log("Foo render");return (<div><h1> Foo </h1></div>);
}
只要点击了 App
组件内的 Change name
按钮,不管 Foo
具体实现是什么,都会被重新render
渲染
- 函数组件重新渲染
function App(){const [name,setName] = useState('App')return (<div className="App"><Foo /><button onClick={() => setName("aaa")}>{ name }</button></div>)
}function Foo() {console.log("Foo render");return (<div><h1> Foo </h1></div>);
}
可以发现,使用useState
来更新状态的时候,只有首次会触发Foo render
,后面并不会导致Foo render
# 三、总结
render
函数里面可以编写JSX
,转化成createElement
这种形式,用于生成虚拟DOM
,最终转化成真实DOM
在React
中,类组件只要执行了 setState
方法,就一定会触发 render
函数执行,函数组件使用useState
更改状态不一定导致重新render
组件的props
改变了,不一定触发 render
函数的执行,但是如果 props
的值来自于父组件或者祖先组件的 state
在这种情况下,父组件或者祖先组件的 state
发生了改变,就会导致子组件的重新渲染
所以,一旦执行了setState
就会执行render
方法,useState
会判断当前值有无发生改变确定是否执行render
方法,一旦父组件发生渲染,子组件也会渲染
# 参考文献
- https://zhuanlan.zhihu.com/p/45091185
- https://juejin.cn/post/6844904181493415950
- 面试官:说说React render方法的原理?在什么时候会被触发? | web前端面试 - 面试官系列
react render相关 【类组件、函数组件 】相关推荐
- Python函数定义相关+“类”作为函数参数
简单函数的定义 def 函数名(形参1, 形参2...):语句1语句2...return xxx 1.只能有一个函数返回值 2.函数语句写 pass 则为空函数,用来作为占位符,比如现在还没想好怎么写 ...
- onclick=两个函数_[译]React函数组件和类组件的差异
[译]React函数组件和类组件的差异 原文: https://overreacted.io/how-are-function-components-different-from-classes/ 在 ...
- React 类组件和函数组件
React 类组件和函数组件 目录 1.类组件和函数组件 2.如何使用 props 和 state 3.如何绑定事件 4.复习 this+ 两个面试题 组件component 一.概念 Element ...
- React函数组件和类组件的区别
定义组件有两个要求: 组件名称必须以大写字母开头 组件的返回值只能有一个根元素 函数组件 函数组件接收一个单一的 props 对象并返回了一个React元素 类组件 class Welcome ext ...
- react基础入门,类组件和函数组件,state,props,refs
React入门 目录 React入门 React入门 Vue跟React的异同点 相同点 不同点 Vue小建议 1. 不需要响应式的数据应该怎么处理? 2. Key 3. 数据结构 React 教程 ...
- react之纯函数、函数组件
纯函数 Pure Function 定义:一个函数的返回结果只依赖于它的参数,并且在执行的过程中没有副作用,我们就把该函数称作纯函数. 特点 1. 函数的返回结果只依赖于它的参数. let foo=( ...
- react18 函数组件 学习笔记
react学习笔记 react 安装 渲染DOM 使用Portal(可以将组件渲染到页面指定位置) 使用方法 CSS_Modal(外部样式表) 使用方式 Fragment (根元素) 使用方式 con ...
- antd 函数组件_React - 组件:函数组件
目录: 1. 组件名字首字母一定是大写的2. 返回一个jsx3. jsx依赖React,所以组件内部需要引入React4. 组件传参 a. 传递.b. 接收. function Component( ...
- React 中ref 的使用(类组件和函数组件)以及forwardRef 与 useImperativeHandle 详解
前言 在一个父组件中,我们想要获取到其中的节点元素或者子组件实例,从而直接调用其上面的方法.Class 类组件和函数组件是两种不同的写法. 1. Class 组件中使用ref 在 React 的 Cl ...
最新文章
- Gartner公布五大新兴技术趋势 AI成主角
- 让PHP开发者事半功倍的十大技巧
- 吴恩达深度学习—— 3.4 多个例子中的向量化
- linux raid5卷,Linux逻辑卷及RAID5的创建
- 《凤凰项目》读书笔记二
- D4 数据分析实例:分析movielens电影数据+pandas核心数据结构
- 清理服务器系统日志,win2008服务器清理系统日志
- Windows无法连接到无线网络
- mdf数据库文件打开
- [学习笔记]多项式与有标号简单图计数
- 日历控件CalendarView的使用
- Polar码的C语言实现之比特反序重排篇
- c语言中float是什么类型的数据,float是什么数据类型?
- CAD控件 出三维控件!和手机CAD控件了,欢迎大家使用!
- Linux常用基础指令
- numpy中rand与randn的区别
- Java安卓适配全面屏_Android APP全面屏适配技术要点
- 标签打印软件如何批量打印小程序码图片
- 2021年剧本杀专题研究报告
- 回归分析:预测 VS 因果分析
热门文章
- QComboBox 设置下拉列表颜色
- anchor机制讲解
- 教你如何用ffmpeg处理音频格式转换(标贝科技)
- Driller源码阅读笔记(二)
- l003 Driller Augmenting Fuzzing Through Selective Symbolic Execution_2016_NDSS学习笔记
- 3G上网:按时长计费是运营商的“最佳选择”
- 根据前序遍历和[中序遍历]
- Java初级程序员与ChatGPT(文心一言)使用感受
- 详解非局部均值滤波原理以及用MATLAB源码实现
- 建立个人网站的基本步骤