反应与 ReactDOM?
React vs ReactDOM?
我有点新反应。我看到我们必须导入两个东西才能开始,React
和 ReactDOM
,任何人都可以解释其中的区别。我正在通读 React documentation,但它没有说。
React 和 ReactDOM 最近才拆分为两个不同的库。在 v0.14 之前,所有 ReactDOM 功能都是 React 的一部分。这可能会造成混淆,因为任何稍微过时的文档都不会提及 React / ReactDOM 的区别。
顾名思义,ReactDOM 是 React 和 DOM 之间的粘合剂。通常,您只会将它用于一件事:使用 ReactDOM.render()
进行安装。 ReactDOM 的另一个有用特性是 ReactDOM.findDOMNode()
,您可以使用它来直接访问 DOM 元素。 (你应该在 React 应用程序中谨慎使用,但它可能是必要的。)如果你的应用程序是 "isomorphic",你也可以在你的后端代码中使用 ReactDOM.renderToString()
。
对于其他一切,都有 React。您使用 React 来定义和创建元素,用于生命周期挂钩等,即 React 应用程序的核心。
React 和 ReactDOM 分成两个库的原因是 React Native 的到来。 React 包含 Web 和移动应用程序中使用的功能。 ReactDOM 功能仅在网络应用程序中使用。 [更新: 经过进一步研究,很明显我对 React Native 的无知正在显现。现在,让 Web 和移动端通用的 React 包似乎更像是一种愿望,而不是现实。 React Native 目前是一个完全不同的包。]
查看宣布 v0.14 版本的博客 post:
https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
来自React v0.14 Beta release announcement.
As we look at packages like react-native
, react-art
, react-canvas
, and react-three
, it's become clear that the beauty and essence of React has nothing to do with browsers or the DOM.
To make this more clear and to make it easier to build more environments that React can render to, we're splitting the main react package into two: react and react-dom.
从根本上说,React 的思想与浏览器无关,它们恰好是将组件树渲染到其中的众多目标之一。 ReactDOM 包允许开发人员从 React 包中删除任何非必要的代码,并将其移动到更合适的存储库中。
The react
package contains React.createElement
, React.createClass
and React.Component
, React.PropTypes
, React.Children
, and the other helpers related to elements and component classes. We think of these as the isomorphic or universal helpers that you need to build components.
The react-dom
package contains ReactDOM.render
, ReactDOM.unmountComponentAtNode
, and ReactDOM.findDOMNode
, and in react-dom/server
we have server-side rendering support with ReactDOMServer.renderToString
and ReactDOMServer.renderToStaticMarkup
.
这两段解释了 v0.13
中的核心 API 方法在哪里结束。
ReactDOM 模块公开了 DOM 特定的方法,而 React 具有旨在由 React 在不同平台(例如 React Native)上共享的核心工具。
在 v0.14 之前它们是主 ReactJs 文件的一部分,但在某些情况下我们可能不需要两者,它们将它们分开并且它从版本 0.14 开始,这样如果我们只需要其中一个,我们的应用程序会因为只使用其中一个而变得更小:
var React = require('react'); /* importing react */
var ReactDOM = require('react-dom'); /* importing react-dom */
var MyComponent = React.createClass({
render: function() {
return <div>Hello World</div>;
}
});
ReactDOM.render(<MyComponent />, node);
React 包包含:React.createElement、React.createClass、React.Component、React.PropTypes, React.Children
React-dom 包包含:ReactDOM.render、ReactDOM.unmountComponentAtNode、ReactDOM.findDOMNode,以及 react-dom/server,其中包括:ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup。
看起来他们已经将 React 分成了 react
和 react-dom
包,所以你不必在你想要的项目中使用 DOM 相关的部分喜欢在非 DOM 特定情况下使用它,例如此处 https://github.com/Flipboard/react-canvas
他们进口的地方
var React = require('react');
var ReactCanvas = require('react-canvas');
如你所见。没有 react-dom
.
更简洁的说,react是针对组件的,react-dom是针对DOM中的组件渲染的。 'react-dom' 充当组件和 DOM 之间的粘合剂。您将使用 react-dom 的 render() 方法来渲染 DOM 中的组件,这就是您开始使用它时必须知道的全部内容。
react package
包含组件、状态、道具和所有反应代码的 react source
。
react-dom
包顾名思义就是glue between React and the DOM
。通常,您只会将它用于一件事情:mounting your application to the index.html file with ReactDOM.render()
.
为什么要分开?
reason
React 和 ReactDOM 被分成两个库是由于 React Native (A react platform for mobile development)
的到来。
React:React 是一个 javascript 库,旨在构建更好的用户界面。
React-DOM:React-DOM 是 React 的免费库,它将 React 粘合到浏览器 DOM
我们正在使用 React,每当我们使用像 render() 或 findDOMNode() 这样的方法时,我们都在使用 React-DOM.
当我们查看 react-native、react-art、react-canvas 和 react-three 等包时,很明显 React 的美丽和本质无关使用浏览器或 DOM。
为了使这一点更清楚并更容易构建更多 React 可以渲染的环境,他们将主要的 React 包分成两个:React 和 react-dom.
react 包包含组件、状态、道具和所有反应代码的反应源。
顾名思义,react-dom 包是 React 和 DOM 之间的粘合剂。通常,您只会将它用于一件事:使用 ReactDOM.render().
将您的应用程序安装到 index.html 文件
TL;TR 创建和使用组件和挂钩需要 react
包,react-dom
包含 react-dom/client
和 react-dom/server
在浏览器的 DOM 或服务器上的字符串(或流)中呈现您的应用程序。使用 react-native
,您可以使用 React 为 Android 和 iOS.
创建原生应用程序
This question has been asked almost seven years ago and a lot has changed since then.
Most of the answer are no longer correct or contains outdated information.
I'll try to give you a complete but simple answer with the most up to date information available.
反应 18
2022 年 3 月 React 18 has been released。它在其 public API 中带来了一些有趣的变化。
套餐
react
如 React 文档中所述:
React is the entry point to the React library. If you load React from a <script>
tag, these top-level APIs are available on the React global.
事实上,它公开了大多数 常见的 React 功能 以创建和使用组件。 其中一些是:
- React.Component and React.PureComponent,用于创建class组件和函数组件
React.createElement()
,用于将您的 JSX 代码从 <Page title="Home page" />
转换为 React.createElement(Page, { title: "Home page" }, null)
- React.Fragment, to return multiple elements without creating additional DOM elements (starting with React 16.2你也可以使用
<></>
创建片段。
- hooks,让您无需编写 class
即可使用状态和其他 React 功能
- Refs, Suspence and Transitions
Complete list of API exposed by the React
object
react-dom
, react-native
and the others listed below are React renderers. They manage how a React tree turns into the underlying platform calls.
react-dom
The react-dom package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside the React model if you need to.
这个包本质上是一个容器,用于将客户端和服务器sub-packages从一个单独的容器中暴露出来。实际上它只公开了两个函数:
createPortal()
, used to create portals 并在父组件的 DOM 层次结构之外渲染子组件
flushSync()
是您可能从未听说过的东西,而且是有原因的。因为它 会严重影响性能 。
从 React 18 开始 这些函数已被标记为 legacy,因此它们将在未来的版本中被弃用:
render()
hydrate()
findDOMNode()
unmountComponentAtNode()
If you are thinking "OMG they have deprecated the ´ReactDOM.render´ method from React", don't worry and read below.
弃用背后的原因是:
the opportunity to redesign the APIs we expose for rendering on the client and server. These changes allow users to continue using the old APIs in React 17 mode while they upgrade to the new APIs in React 18.
请记住,如果您继续使用那些遗留 API,新的 React 18 功能将被禁用。
Complete list of API exposed by the react-dom
package
react-dom/client
The react-dom/client package provides client-specific methods used for initializing an app on the client. Most of your components should not need to use this module.
React DOM 客户端模块只公开了两个方法:
createRoot()
是在您的应用所在的位置创建根目录的新方法。这是 ReactDOM.render
的 替换 - 请参见下面的示例
hydrateRoot()
是 ReactDOM.hydrate
的替代品,需要水化服务器呈现的应用程序
现在呈现应用程序的 惯用方式 是使用 createRoot
和 render
链接在一起:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
ReactDOM
.createRoot(document.getElementById('root'))
.render(<h1>Hello, world!</h1>);
如果您不喜欢链接,也可以使用常量,这只是风格问题:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/client
package
react-dom/server
The ReactDOMServer object enables you to render components to static markup. Typically, it’s used on a Node server
使用 ReactDOMServer,您可以渲染 React 组件 server-side。它提供了广泛的方法来实现这一点 - 每个环境都有专用功能:
renderToPipeableStream()
,使用 Node.js 流
renderToNodeStream()
(Deprecated),使用 Node.js 流
renderToStaticNodeStream()
,使用 Node.js 流
renderToReadableStream()
,使用浏览器中可用的 Web Streams,Deno,...
此外,还有render可以在不支持流的环境下使用:
renderToString()
对 React 18 感到沮丧
renderToStaticMarkup()
You can use them but they have limited Suspense support.
这是您自己尝试 ReactDOMServer 的最小工作示例:
import React from 'react';
import * as ReactDOMServer from 'react-dom/server';
const html = ReactDOMServer.renderToString(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/server
package
react-native
With React Native, React primitives render to native platform UI, meaning your app uses the same native platform APIs other apps do.
React Native 现在本身就有一个巨大的生态系统,它不仅限于 render 个组件。
今天不再建议安装 react-native
module yourself. Instead, you can use the the expo-cli 以利用其自动化开发您的应用程序。
其他 React 渲染器
These are some of the most interesting renderer available today (not dead) for React
react-canvas
react-canvas
项目 is dead,但类似的功能可以在
react-konva。使用它你可以在 HTML canvas.
中渲染你的 React 组件
react-three
react-three
has been superseded by react-three-fiber
. It allows you to build your three.js 来自 React 的声明式场景。
墨水
ink
是 CLI 的 React 渲染器。使用它,您可以使用组件构建 CLI 输出。
react-figma
react-figma
是 Figma 的 React 渲染器。您可以使用 React 组件作为设计的来源。
react-pdf
react-pdf
是一个 React 渲染器,用于在浏览器和服务器上创建 PDF 文件。
常见问题
prop-types
去哪儿了?
随着 react 15.5 prop-types
库的发布
移出 React 进入 a dedicated package.
我有点新反应。我看到我们必须导入两个东西才能开始,React
和 ReactDOM
,任何人都可以解释其中的区别。我正在通读 React documentation,但它没有说。
React 和 ReactDOM 最近才拆分为两个不同的库。在 v0.14 之前,所有 ReactDOM 功能都是 React 的一部分。这可能会造成混淆,因为任何稍微过时的文档都不会提及 React / ReactDOM 的区别。
顾名思义,ReactDOM 是 React 和 DOM 之间的粘合剂。通常,您只会将它用于一件事:使用 ReactDOM.render()
进行安装。 ReactDOM 的另一个有用特性是 ReactDOM.findDOMNode()
,您可以使用它来直接访问 DOM 元素。 (你应该在 React 应用程序中谨慎使用,但它可能是必要的。)如果你的应用程序是 "isomorphic",你也可以在你的后端代码中使用 ReactDOM.renderToString()
。
对于其他一切,都有 React。您使用 React 来定义和创建元素,用于生命周期挂钩等,即 React 应用程序的核心。
React 和 ReactDOM 分成两个库的原因是 React Native 的到来。 React 包含 Web 和移动应用程序中使用的功能。 ReactDOM 功能仅在网络应用程序中使用。 [更新: 经过进一步研究,很明显我对 React Native 的无知正在显现。现在,让 Web 和移动端通用的 React 包似乎更像是一种愿望,而不是现实。 React Native 目前是一个完全不同的包。]
查看宣布 v0.14 版本的博客 post: https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
来自React v0.14 Beta release announcement.
As we look at packages like
react-native
,react-art
,react-canvas
, andreact-three
, it's become clear that the beauty and essence of React has nothing to do with browsers or the DOM.To make this more clear and to make it easier to build more environments that React can render to, we're splitting the main react package into two: react and react-dom.
从根本上说,React 的思想与浏览器无关,它们恰好是将组件树渲染到其中的众多目标之一。 ReactDOM 包允许开发人员从 React 包中删除任何非必要的代码,并将其移动到更合适的存储库中。
The
react
package containsReact.createElement
,React.createClass
andReact.Component
,React.PropTypes
,React.Children
, and the other helpers related to elements and component classes. We think of these as the isomorphic or universal helpers that you need to build components.The
react-dom
package containsReactDOM.render
,ReactDOM.unmountComponentAtNode
, andReactDOM.findDOMNode
, and inreact-dom/server
we have server-side rendering support withReactDOMServer.renderToString
andReactDOMServer.renderToStaticMarkup
.
这两段解释了 v0.13
中的核心 API 方法在哪里结束。
ReactDOM 模块公开了 DOM 特定的方法,而 React 具有旨在由 React 在不同平台(例如 React Native)上共享的核心工具。
在 v0.14 之前它们是主 ReactJs 文件的一部分,但在某些情况下我们可能不需要两者,它们将它们分开并且它从版本 0.14 开始,这样如果我们只需要其中一个,我们的应用程序会因为只使用其中一个而变得更小:
var React = require('react'); /* importing react */
var ReactDOM = require('react-dom'); /* importing react-dom */
var MyComponent = React.createClass({
render: function() {
return <div>Hello World</div>;
}
});
ReactDOM.render(<MyComponent />, node);
React 包包含:React.createElement、React.createClass、React.Component、React.PropTypes, React.Children
React-dom 包包含:ReactDOM.render、ReactDOM.unmountComponentAtNode、ReactDOM.findDOMNode,以及 react-dom/server,其中包括:ReactDOMServer.renderToString 和 ReactDOMServer.renderToStaticMarkup。
看起来他们已经将 React 分成了 react
和 react-dom
包,所以你不必在你想要的项目中使用 DOM 相关的部分喜欢在非 DOM 特定情况下使用它,例如此处 https://github.com/Flipboard/react-canvas
他们进口的地方
var React = require('react');
var ReactCanvas = require('react-canvas');
如你所见。没有 react-dom
.
更简洁的说,react是针对组件的,react-dom是针对DOM中的组件渲染的。 'react-dom' 充当组件和 DOM 之间的粘合剂。您将使用 react-dom 的 render() 方法来渲染 DOM 中的组件,这就是您开始使用它时必须知道的全部内容。
react package
包含组件、状态、道具和所有反应代码的 react source
。
react-dom
包顾名思义就是glue between React and the DOM
。通常,您只会将它用于一件事情:mounting your application to the index.html file with ReactDOM.render()
.
为什么要分开?
reason
React 和 ReactDOM 被分成两个库是由于 React Native (A react platform for mobile development)
的到来。
React:React 是一个 javascript 库,旨在构建更好的用户界面。
React-DOM:React-DOM 是 React 的免费库,它将 React 粘合到浏览器 DOM
我们正在使用 React,每当我们使用像 render() 或 findDOMNode() 这样的方法时,我们都在使用 React-DOM.
当我们查看 react-native、react-art、react-canvas 和 react-three 等包时,很明显 React 的美丽和本质无关使用浏览器或 DOM。 为了使这一点更清楚并更容易构建更多 React 可以渲染的环境,他们将主要的 React 包分成两个:React 和 react-dom.
react 包包含组件、状态、道具和所有反应代码的反应源。
顾名思义,react-dom 包是 React 和 DOM 之间的粘合剂。通常,您只会将它用于一件事:使用 ReactDOM.render().
将您的应用程序安装到 index.html 文件TL;TR 创建和使用组件和挂钩需要 react
包,react-dom
包含 react-dom/client
和 react-dom/server
在浏览器的 DOM 或服务器上的字符串(或流)中呈现您的应用程序。使用 react-native
,您可以使用 React 为 Android 和 iOS.
This question has been asked almost seven years ago and a lot has changed since then. Most of the answer are no longer correct or contains outdated information. I'll try to give you a complete but simple answer with the most up to date information available.
反应 18
2022 年 3 月 React 18 has been released。它在其 public API 中带来了一些有趣的变化。
套餐
react
如 React 文档中所述:
React is the entry point to the React library. If you load React from a
<script>
tag, these top-level APIs are available on the React global.
事实上,它公开了大多数 常见的 React 功能 以创建和使用组件。 其中一些是:
- React.Component and React.PureComponent,用于创建class组件和函数组件
React.createElement()
,用于将您的 JSX 代码从<Page title="Home page" />
转换为React.createElement(Page, { title: "Home page" }, null)
- React.Fragment, to return multiple elements without creating additional DOM elements (starting with React 16.2你也可以使用
<></>
创建片段。 - hooks,让您无需编写 class 即可使用状态和其他 React 功能
- Refs, Suspence and Transitions
Complete list of API exposed by the React
object
react-dom
,react-native
and the others listed below are React renderers. They manage how a React tree turns into the underlying platform calls.
react-dom
The react-dom package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside the React model if you need to.
这个包本质上是一个容器,用于将客户端和服务器sub-packages从一个单独的容器中暴露出来。实际上它只公开了两个函数:
createPortal()
, used to create portals 并在父组件的 DOM 层次结构之外渲染子组件flushSync()
是您可能从未听说过的东西,而且是有原因的。因为它 会严重影响性能 。
从 React 18 开始 这些函数已被标记为 legacy,因此它们将在未来的版本中被弃用:
render()
hydrate()
findDOMNode()
unmountComponentAtNode()
If you are thinking "OMG they have deprecated the ´ReactDOM.render´ method from React", don't worry and read below.
弃用背后的原因是:
the opportunity to redesign the APIs we expose for rendering on the client and server. These changes allow users to continue using the old APIs in React 17 mode while they upgrade to the new APIs in React 18.
请记住,如果您继续使用那些遗留 API,新的 React 18 功能将被禁用。
Complete list of API exposed by the react-dom
package
react-dom/client
The react-dom/client package provides client-specific methods used for initializing an app on the client. Most of your components should not need to use this module.
React DOM 客户端模块只公开了两个方法:
createRoot()
是在您的应用所在的位置创建根目录的新方法。这是ReactDOM.render
的 替换 - 请参见下面的示例hydrateRoot()
是ReactDOM.hydrate
的替代品,需要水化服务器呈现的应用程序
现在呈现应用程序的 惯用方式 是使用 createRoot
和 render
链接在一起:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
ReactDOM
.createRoot(document.getElementById('root'))
.render(<h1>Hello, world!</h1>);
如果您不喜欢链接,也可以使用常量,这只是风格问题:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/client
package
react-dom/server
The ReactDOMServer object enables you to render components to static markup. Typically, it’s used on a Node server
使用 ReactDOMServer,您可以渲染 React 组件 server-side。它提供了广泛的方法来实现这一点 - 每个环境都有专用功能:
renderToPipeableStream()
,使用 Node.js 流renderToNodeStream()
(Deprecated),使用 Node.js 流renderToStaticNodeStream()
,使用 Node.js 流renderToReadableStream()
,使用浏览器中可用的 Web Streams,Deno,...
此外,还有render可以在不支持流的环境下使用:
renderToString()
对 React 18 感到沮丧
renderToStaticMarkup()
You can use them but they have limited Suspense support.
这是您自己尝试 ReactDOMServer 的最小工作示例:
import React from 'react';
import * as ReactDOMServer from 'react-dom/server';
const html = ReactDOMServer.renderToString(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/server
package
react-native
With React Native, React primitives render to native platform UI, meaning your app uses the same native platform APIs other apps do.
React Native 现在本身就有一个巨大的生态系统,它不仅限于 render 个组件。
今天不再建议安装 react-native
module yourself. Instead, you can use the the expo-cli 以利用其自动化开发您的应用程序。
其他 React 渲染器
These are some of the most interesting renderer available today (not dead) for React
react-canvas
react-canvas
项目 is dead,但类似的功能可以在
react-konva。使用它你可以在 HTML canvas.
react-three
react-three
has been superseded by react-three-fiber
. It allows you to build your three.js 来自 React 的声明式场景。
墨水
ink
是 CLI 的 React 渲染器。使用它,您可以使用组件构建 CLI 输出。
react-figma
react-figma
是 Figma 的 React 渲染器。您可以使用 React 组件作为设计的来源。
react-pdf
react-pdf
是一个 React 渲染器,用于在浏览器和服务器上创建 PDF 文件。
常见问题
prop-types
去哪儿了?
随着 react 15.5 prop-types
库的发布
移出 React 进入 a dedicated package.