参考文章
组件显示到屏幕之前,其必须被 React 渲染。理解这些处理步骤将有助于思考代码的执行过程并能解释其行为。
React 请求和提供 UI 的过程总共包括三个步骤:
触发 ——> 渲染 ——> 提交
有两种原因会导致组件的渲染:
当应用启动时,会触发初次渲染。框架和沙箱有时会隐藏这部分代码,但它是通过调用目标 DOM 节点的 createRoot
,然后用组件调用 render
函数完成的:
// index.js
import Image from './Image.js';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'))
root.render(<Image />);
// Image.js
export default function Image() {
return (
<img
src="https://i.imgur.com/ZF6s192.jpg"
alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals"
/>
);
}
试着注释掉 root.render()
,然后将会看到组件消失。
一旦组件被初次渲染,就可以通过使用 set
函数 更新其状态来触发之后的渲染。更新组件的状态会自动将一次渲染送入队列。
状态更新… ——> …触发… ——> …渲染!
在触发渲染后,React 会调用组件来确定要在屏幕上显示的内容。“渲染中” 即 React 在调用组件。
这个过程是递归的:如果更新后的组件会返回某个另外的组件,那么 React 接下来就会渲染 那个 组件,而如果那个组件又返回了某个组件,那么 React 接下来就会渲染 那个 组件,以此类推。这个过程会持续下去,直到没有更多的嵌套组件并且 React 确切知道哪些东西应该显示到屏幕上为止。
在下面的代码示例中,React 将会调用 Gallery()
和 Image()
若干次:
// Gallery.js
export default function Gallery() {
return (
<section>
<h1>鼓舞人心的雕塑</h1>
<Image />
<Image />
<Image />
</section>
);
}
function Image() {
return (
<img
src="https://i.imgur.com/ZF6s192.jpg"
alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals"
/>
);
}
// index.js
import Gallery from './Gallery.js';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'))
root.render(<Gallery />);
、
和三个
标签 创建 DOM 节点。注意:渲染必须始终是一次 纯计算:
否则,随着代码库复杂性的增加,可能会遇到令人困惑的错误和不可预测的行为。在 “严格模式” 下开发时,React 会调用每个组件的函数两次,这可以帮助发现由不纯函数引起的错误。
在渲染(调用)组件之后,React 将会修改 DOM。
appendChild()
DOM API 将其创建的所有 DOM 节点放在屏幕上。React 仅在渲染之间存在差异时才会更改 DOM 节点。 例如,有一个组件,它每秒使用从父组件传递下来的不同属性重新渲染一次。注意,可以添加一些文本到 标签,更新它的
value
,但是文本不会在组件重渲染时消失:
// Clock.js
export default function Clock({ time }) {
return (
<>
<h1>{time}</h1>
<input />
</>
);
}
这个例子之所以会正常运行,是因为在最后一步中,React 只会使用最新的 time
更新 标签的内容。它看到
标签出现在 JSX 中与上次相同的位置,因此 React 不会修改
标签或它的
value
!
在渲染完成并且 React 更新 DOM 之后,浏览器就会重新绘制屏幕。尽管这个过程被称为“浏览器渲染”(“browser rendering”),但我们还是将它称为“绘制”(“painting”),以避免在这些文档的其余部分中出现混淆。