React vs ReactDOM?

我对反应有点陌生。我看到我们必须导入两个东西才能开始,ReactReactDOM,谁能解释一下它们的区别吗?我正在阅读反应的文档,但它没有说。

78448 次浏览

React和ReactDOM最近才被分成两个不同的库。在v0.14之前,所有的React功能都是React的一部分。这可能是一个困惑的来源,因为任何稍微过时的文档都不会提到React / ReactDOM的区别。

顾名思义,ReactDOM是React和DOM之间的粘合剂。通常,你只会用它做一件事:用ReactDOM.render()挂载。ReactDOM的另一个有用的特性是ReactDOM.findDOMNode(),你可以使用它来直接访问DOM元素。(在React应用程序中应该少用,但可能是必要的。)如果你的应用是“同构”的,你也可以在后端代码中使用ReactDOM.renderToString()

对于其他的事情,有React。你使用React来定义和创建你的元素,用于生命周期钩子等,即React应用程序的核心。

React和React dom被分成两个库的原因是React Native的到来。React包含在web和移动应用程序中使用的功能。ReactDOM功能仅在web应用中使用。[更新:经过进一步的研究,很明显我对React Native的无知正在显现。现在,让React包在网络和移动设备上都通用似乎更像是一种愿望,而不是现实。React Native目前是一个完全不同的包。

查看宣布v0.14发布的博客文章: https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html < / p >

React v0.14 Beta发布公告

当我们看到react-nativereact-artreact-canvasreact-three这样的包时,很明显,React的美丽和本质与浏览器或DOM无关。

为了更清楚地说明这一点,也为了更容易地构建更多React可以渲染的环境,我们将主要的React包分为两个:React和React -dom。

从根本上说,React的想法与浏览器无关,它们只是渲染组件树的众多目标之一。React包允许开发人员从React包中删除任何不必要的代码,并将其移动到更合适的存储库中。

react包包含React.createElementReact.createClassReact.ComponentReact.PropTypesReact.Children,以及其他与元素和组件类相关的帮助程序。我们认为这些是构建组件所需的同构的或普遍的帮助器。

react-dom包包含ReactDOM.renderReactDOM.unmountComponentAtNodeReactDOM.findDOMNode,在react-dom/server中,我们通过ReactDOMServer.renderToStringReactDOMServer.renderToStaticMarkup提供服务器端渲染支持。

这两段解释了来自v0.13的核心API方法的结束位置。

ReactDOM模块公开了dom特定的方法,而React拥有核心工具,旨在由React在不同平台上共享(例如React Native)。

http://facebook.github.io/react/docs/tutorial.html

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);

< em > < / em >反应包包含:React。createElement,反应。createClass,反应。组件,反应。proptype,反应。孩子们

< em > React-dom < / em >包包含:ReactDOM。渲染,ReactDOM。unmountComponentAtNode ReactDOM。findDOMNode和react-dom/server,包括:ReactDOMServer。renderToString和ReactDOMServer.renderToStaticMarkup。

看起来他们已经把React分成reactreact-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代码的react source

react-dom包顾名思义就是glue between React and the DOM. react-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代码的react源。

React - DOM包顾名思义是React和DOM之间的粘合剂。通常,您只会将它用于一件事:使用ReactDOM.render()将应用程序挂载到index.html文件。

TL, TR __ABC0包是创建和使用组件和钩子所必需的,__ABC1包含__ABC2和__ABC3来在浏览器的DOM中或在服务器上的字符串(或流)中呈现你的应用程序。通过react-native,你可以使用React创建Android和iOS的原生应用程序。


这个问题在七年前就被提出了,从那时起发生了很多变化。 大部分答案不再正确或包含过时的信息。 我会尽量用最新的信息给你一个完整而简单的答案

反应18

2022年3月React 18已经发布。它在其公共api中带来了一些有趣的变化。

react

如React文档中所述:

React是React库的入口点。如果你从<script>标签加载React,这些顶级api在React全局中可用。

实际上,它公开了大部分React常用特性来创建和使用组件。一些是:

React对象公开的API的完整列表

react-domreact-native和下面列出的其他< >强反应渲染器< / >强。它们管理React树如何转换为底层平台调用。

react-dom

React -dom包提供了特定于dom的方法,可以在应用程序的顶层使用,如果需要,也可以作为逃离React模型的出口。

这个包本质上是一个容器,用于从一个包中公开客户端和服务器的子包。实际上,它只暴露了两个函数:

从React 18 这些函数被标记为legacy开始,所以它们将在未来的版本中被弃用:

  • render()
  • hydrate()
  • findDOMNode()
  • unmountComponentAtNode()

如果你想的是“OMG,他们已经弃用了´ReactDOM。React中的render´方法",不要担心,阅读下面的内容。

弃用背后的原因是:

重新设计我们在客户端和服务器上呈现的api的机会。这些变化允许用户在升级到React 18的新api时,继续在React 17模式下使用旧的api。

记住,如果你继续使用这些遗产 api, React 18的新功能将被禁用。

react-dom包公开的API的完整列表

react-dom/client

react-dom/client包提供了客户端特定的方法,用于在客户端初始化应用程序。您的大多数组件都不需要使用这个模块。

React DOM Client模块只公开了两个方法:

  • createRoot()是创建根目录的新方法。这是替换ReactDOM.render -见下面的例子
  • hydrateRoot()ReactDOM.hydrate的替代品,需要为服务器呈现的应用程序补水

现在渲染你的应用程序的惯用的方法使用createRootrender链接在一起:

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>);

react-dom/client包公开的API的完整列表

react-dom/server

ReactDOMServer对象使您能够将组件呈现为静态标记。通常,它在Node服务器上使用

使用ReactDOMServer你可以在服务器端渲染React组件。它提供了广泛的方法来实现这一点-每个环境都有专门的功能:

此外,还有一些渲染可以在不支持流的环境中使用:

你可以使用它们,但它们有有限的悬念支持。

这是一个最小的工作示例,尝试自己的ReactDOMServer:

import React from 'react';
import * as ReactDOMServer from 'react-dom/server';


const html = ReactDOMServer.renderToString(<h1>Hello, world!</h1>);

react-dom/server包公开的API的完整列表

react-native

使用React Native, React原语呈现到本机平台UI,这意味着你的应用程序使用与其他应用程序相同的本机平台api。

反应本地本身现在有一个巨大的生态系统,它不仅仅局限于渲染组件。

今天不再推荐安装react-native模块自己。相反,你可以使用expo-cli来利用它的自动化来开发应用程序。


其他React渲染器

这些是目前React中最有趣的渲染器

react-canvas

react-canvas项目是死的,但类似的特征可以在 react-konva。使用它你可以在HTML画布中渲染你的React组件

react-three

react-three已被react-three-fiber所取代。它允许你从React中声明式地构建场景。

墨水

ink是一个用于cli的React渲染器。使用它,您可以使用组件构建CLI输出。

react-figma

react-figma是一个用于Figma的React渲染器。你可以使用React组件作为你的设计来源。

react-pdf

react-pdf是一个React渲染器,用于在浏览器和服务器上创建PDF文件。


常见问题解答

prop-types去哪里了?

随着15.5反应的发布,prop-types库 移动到React外面的专用软件包.