Thinking in React
等待资源加载和大部分情况下浏览器的单线程执行是影响web运行的两大原因。
react如何利用组件库解决?
Before we start, you need to know
JSX是JavaScript XML的缩写,它是React中一种用于定义UI组件结构的语法扩展。
JSX使用类似HTML的语法结构,允许开发者在JavaScript代码中直接声明UI组件。JSX的代码结构相对于使用React.createElement方法创建UI组件的代码更加简洁易读,因此成为了React的主流写法
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
它是一种可以让开发者在函数组件中使用React特性的函数。通过使用Hook,开发者可以在不编写类组件的情况下使用状态、生命周期等特性,从而使代码更加简洁和易于维护
suspense
React.Suspense是React 16.6中引入的新功能,它允许我们在组件树中等待异步加载的内容并显示一个指定的fallback,以增强用户体验。
import React, { Suspense } from 'react';
const MyLazyComponent = React.lazy(() => import('./MyLazyComponent'));
function App() {
return (
<div>
<h1>Welcome to my app!</h1>
<Suspense fallback={<div>Loading...</div>}>
<MyLazyComponent />
</Suspense>
</div>
);
}
export default App;
在上面的示例中,我们使用React.lazy()异步加载了一个名为MyLazyComponent的组件。然后,在App组件中,我们将MyLazyComponent组件包装在一个React.Suspense组件中,并指定一个fallback,即在MyLazyComponent加载完成之前显示的内容。在这种情况下,我们只是简单地显示了一个“Loading...”文本。
errorBoundary
Error Boundary是React 16中引入的一个新概念,它可以在子组件中发生错误时捕获这些错误,防止整个应用程序崩溃,并显示备用UI。
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Oops, something went wrong!</h1>;
}
return this.props.children;
}
}
class MyComponent extends Component {
render() {
if (this.props.shouldThrowError) {
throw new Error('Something went wrong!');
}
return <div>Hello, World!</div>;
}
}
function App() {
return (
<div>
<h1>Welcome to my app!</h1>
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
</div>
);
}
export default App;
在App组件中,我们将MyComponent组件包装在一个ErrorBoundary组件中。当MyComponent组件抛出一个错误时,ErrorBoundary组件会捕获这个错误,并显示一个备用UI(在这种情况下,只是一个简单的“Oops, something went wrong!”文本)。
更新流程
React的更新流程是一个比较复杂的过程,可以分为三个阶段:Reconciliation(协调)、Render(渲染)和Commit(提交)。
- Reconciliation(协调)阶段
在Reconciliation阶段,React会比较前后两次渲染的虚拟DOM树,找出哪些节点需要更新。具体流程如下:
- 首先,React会对新旧虚拟DOM树的根节点进行比较,如果类型不同,则整个树需要重新构建;如果类型相同,则继续进行子节点的比较。
- React会对同级节点进行比较,如果节点类型不同,则进行替换;如果节点类型相同,则继续进行子节点的比较。
- 如果节点是一个文本节点,React会直接替换内容。
- React会根据每个节点的key值进行比较,找到需要更新的节点。
在这个阶段,React会标记哪些组件需要更新,并把更新放在队列中,等待后续处理。
- Render(渲染)阶段
在Render阶段,React会根据需要更新的组件和状态,重新生成虚拟DOM树。具体流程如下:
- React会根据需要更新的组件和状态,重新调用组件的render方法生成虚拟DOM树。
- React会对虚拟DOM树进行遍历,生成一份新的fiber树,用于后续的更新和提交。
在这个阶段,React不会进行实际的DOM操作,只是生成一份新的fiber树,用于下一步的更新。
- Commit(提交)阶段
在Commit阶段,React会把需要更新的内容提交到浏览器中,实际更新DOM。具体流程如下:
- React会遍历更新队列,根据需要更新的内容进行实际的DOM操作。
- React会触发组件的生命周期方法,例如componentDidMount和componentDidUpdate等。
在这个阶段,React会进行实际的DOM操作,更新页面显示。更新完成后,React会进入空闲状态,等待下一次更新。
Scheduler
Reconciler
Renderer
常见APT与Hook