react 源码概览
共 2636字,需浏览 6分钟
·
2020-12-06 12:24
React 采用 monorepo 的管理方式。仓库中包含多个独立的包,以便于更改可以一起联调,并且问题只会出现在同一地方。
react
React “Core” 中包含所有全局 React API,比如:
1、React.createElement()
2、React.Component
3、React.Children
React 核心只包含定义组件必要的 API。它不包含协调算法或者其他平台特定的代码。它同时适用于 React DOM 和 React Native 组件。
React 核心代码在源码的 packages/react 目录中。在 npm 上发布为 react 包。相应的独立浏览器构建版本称为 react.js,它会导出一个称为 React 的全局对象。
import React from 'react';
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}h1>;
}
}
react-dom
React 最初只是服务于 DOM,但是这之后被改编成也能同时支持原生平台的 React Native。因此,在 React 内部机制中引入了“渲染器”这个概念。
渲染器用于管理一棵 React 树,使其根据底层平台进行不同的调用。
渲染器同样位于 packages/ 目录下:
React DOM Renderer 将 React 组件渲染成 DOM。它实现了全局 ReactDOMAPI,这在npm上作为 react-dom 包。这也可以作为单独浏览器版本使用,称为 react-dom.js,导出一个 ReactDOM 的全局对象.
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!h1>,
document.getElementById('root')
);
react-native
React Native使你只使用JavaScript也能编写原生移动应用。它在设计原理上和React一致,通过声明式的组件机制来搭建丰富多彩的用户界面。
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class WhyReactNativeIsSoGreat extends Component {
render() {
return (
<View>
<Text>
如果你喜欢在Web上使用React,那你也肯定会喜欢React Native.
Text>
<Text>
基本上就是用原生组件比如'View'和'Text'
来代替web组件'div'和'span'。
Text>
View>
);
}
}
React Native Renderer 将 React 组件渲染为 Native 视图。此渲染器在 React Native 内部使用。
React Native 产出的并不是“网页应用”, 或者说“HTML5应用”,又或者“混合应用”。最终产品是一个真正的移动应用,从使用感受上和用 Objective-C 或 Java 编写的应用相比几乎是无法区分的。React Native 所使用的基础UI组件和原生应用完全一致。你要做的就是把这些基础组件使用JavaScript 和 React 的方式组合起来。
react-test-renderer
React Test Renderer 将 React 组件渲染为 JSON 树。这用于 Jest 的快照测试特性。在 npm 上作为 react-test-renderer 包发布。
import TestRenderer from 'react-test-renderer';
function Link(props) {
return <a href={props.page}>{props.children}a>;
}
const testRenderer = TestRenderer.create(
<Link page="https://www.facebook.com/">FacebookLink>
);
console.log(testRenderer.toJSON());
// { type: 'a',
// props: { href: 'https://www.facebook.com/' },
// children: [ 'Facebook' ] }
本质上,该包可以在无需使用浏览器或 jsdom 的情况下,轻松地抓取由 React DOM 或 React Native渲染出的平台视图层次结构(类似于DOM树)。
reconciler
即便 React DOM 和 React Native 渲染器的区别很大,但也需要共享一些逻辑。特别是协调算法需要尽可能相似,这样可以让声明式渲染,自定义组件,state,生命周期方法和 refs 等特性,保持跨平台工作一致。
为了解决这个问题,不同的渲染器彼此共享一些代码。我们称 React 的这一部分为 “reconciler”。当处理类似于 setState() 这样的更新时,reconciler 会调用树中组件上的 render(),然后决定是否进行挂载,更新或是卸载操作。
Reconciler 没有单独的包,因为他们暂时没有公共 API。相反,它们被如 React DOM 和 React Native 的渲染器排除在外。
协调就是不同的渲染器彼此共享的一些代码,包括 diff 算法。当组件的 props 或 state 发生变化时,React 通过将最新返回的元素与原先渲染的元素进行比较,来决定是否有必要进行一次实际的 DOM 更新。当它们不相等时,React 才会更新 DOM。这个过程被称为“协调”。
“stack” reconciler 是 React 15 及更早的解决方案。Fiber 从 React 16 开始变成了默认的 reconciler。