探究React的渲染

2023-10-16 15:26:24 浏览数 (1)

React本质上是建立用户界面的库。一个公式有助于理解React:view=function(state),或简写为v=f(s)。下一个问题是:React在什么时间、如何更新视图?回答这个问题之前,我们先弄清楚——什么是渲染?

本文内容来自React.gg。

什么是渲染(rendering)

长话短说,渲染是指React调用部件(Component)更新视图。

React渲染部件的时候会发生两件事。首先React会为需要渲染的部件创建快照,这个快照包含属性、状态、事件处理函数,以及UI的描述。

为了得到你的应用的初始UI,React需要做初始的渲染,这个初始渲染发生在root上。

代码语言:javascript复制
import { createRoot } from "react-dom/client";
import App from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);

当然,有趣的事都发生在初始渲染之后的子渲染上。那么,到底React在什么时候重新渲染一个部件?像上面公式所示,当s变化的时候,f被激活。

React什么时候重新渲染(re-rendering)

触发React部件重新渲染的唯一条件是状态的改变。React怎么知道部件的状态发生了改变?与上面提到的快照有关。当事件处理函数(event handler)被激活,函数会访问部件的属性(props)和状态(state),这些属性和状态都已经被保存在快照里的。

如果事件处理函数包含改变状态的内容,React会比较新的状态与快照中保存的状态,如果状态发生改变,会处罚部件的的重新渲染——创建新的快照,更新视图。

现在我们已经建立了React渲染原理的心智模型,接下来是实践时间。假设我们需要一个简单的应用,用户点击按钮后切换不同的问候语。为了实现这个功能,我们将问候语放入一个数组,然后用状态index存储当前的问候语。用户点击按钮后,或者增加index的值,如果到达数组最后一个元素,则将其重置为0。代码如下:

代码语言:javascript复制
import * as React from "react"

function Greeting ({ name }) {
 const [index, setIndex] = React.useState(0)

 const greetings = ['Hello', "Hola", "Bonjour"]

 const handleClick = () => {
 const nextIndex = index === greetings.length - 1
 ? 0
 : index   1
 setIndex(nextIndex)
 }

 return (
 <main>
 <h1>{greetings[index]}, {name}</h1>
 <button onClick={handleClick}>Next Greeting</button>
 </main>
 )
}

export default function App () {
 return <Greeting name="Tyler" />
}

现在只要按钮被点击,handleClick事件处理程序就会运行。handleClick中的状态index与最近的快照中的状态相同。事件处理程序中React看到有一个对setIndex的调用,并且传递给它的值与快照中的状态不同,因此触发了重新渲染。

现在看另一段代码:

代码语言:javascript复制
import * as React from "react"

export default function VibeCheck () {
 const [status, setStatus] = React.useState("clean")

 const handleClick = () => {
 setStatus("dirty")
 alert(status)
 }

 return (
 <button onClick={handleClick}>
 {status}
 </button>
 )
}

这个例子与上面的没有什么不同。

handleClick事件处理程序运行时,它访问快照创建时的propsstate——在那个时刻,state的值是clean。因此提醒的状态是clean

再次点击按钮,因为之前的按钮点击触发了重新渲染,并创建了一个新的快照,其状态为dirty,在最初的点击之后的任何点击中,我们都会得到dirty

继续,下面的代码中,点击按钮后会发生什么?

代码语言:javascript复制
import * as React from "react"

export default function Counter () {
 console.count("Rendering Counter")
 const [count, setCount] = React.useState(0)

 const handleClick = () => {
 console.count("click")
 setCount(count)
 }

 return (
 <button onClick={handleClick}>
 


	

0 人点赞