React 顶层 API
React
是 React 库的入口。如果你用 <script>
标签来加载 React,这些顶级 API 都在 React
这个全局变量上。如果你在 npm 下使用 ES6 ,你可以这样写 import React from 'react'
。如果你在 npm 下使用 ES5,你可以这样写 var React = require('react')
。
概述
组件(Components)
React 组件允许你将UI拆分为独立的可重用的模块,并且每个模块逻辑也是独立的。 React组件可以通过扩展 React.Component
或 React.PureComponent
来定义。
如果你不使用 ES6 类(classes),你也可以使用 create-react-class
模块来替代。 查看 不使用 ES6 的 React 以获取更多相关信息。
React组件也可以定义为被包裹的函数:
创建 React 元素
我们建议 使用 JSX 来描述你的 UI 应该是什么样。每个 JSX 元素都是调用 React.createElement()
的语法糖。 如果使用 JSX ,你不必显示地调用下面的方法。
查阅 不使用 JSX 的 React 获取更多信息。
转换元素
React
还提供了一些其他的 API :
片段(Fragments)
React
还提供了一个用于渲染多个元素而没有包裹元素的组件。
Refs
Suspense
Suspense 允许组件在渲染之前“等待”某些东西。 目前,Suspense 只支持一个用例:使用React.lazy
动态加载组件。 将来,它将支持其他用例,如数据获取。
参考
React.Component
React.Component
是 React 组件使用 ES6 类(classes) 定义时的基类。
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
有关 React.Component
基类相关的方法和属性,请参阅React.Component API参考。
React.PureComponent
React.PureComponent
与 React.Component
完全相同,但是在shouldComponentUpdate()
中实现时,使用了 props 和 state 的浅比较。
如果你的React组件的 render()
函数在给定相同 props 和 state 情况下渲染相同的结果,在某些情况下,你可以使用React.PureComponent
来提高性能。
注意:
React.PureComponent
的shouldComponentUpdate()
仅对对象进行浅比较。 如果这些包含复杂的数据结构,它可能会在更深层数据差异比较时发生判断偏差。 所以扩展PureComponent
只能用于具有简单 props 和 state 的组件,或者在知道深层数据结构已更改时使用forceUpdate()
来强制更新的组件。 或者,考虑使用不可变对象来帮助嵌套数据的快速比较。再者,
React.PureComponent
的shouldComponentUpdate()
方法跳过了整个组件子树的 props 更新。所以确保所有的子组件也是“pure”。
React.memo
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
React.memo
是一个高阶组件。 它与 React.PureComponent
类似,但是他用于包裹函数式组件,而不是类组件。
如果你的函数式组件在给定相同的 props 的情况下渲染相同的结果,你可以在调用 React.memo
将其包装起来,以便在某些情况下通过记忆结果来提高性能。 这意味着 React 将跳过组件渲染,并重用最后渲染的结果。
默认情况下,它只会浅显比较 props 对象中的复杂对象。 如果要控制比较,还可以提供自定义比较函数作为第二个参数。
function MyComponent(props) {
/* render using props */
}
function areEqual(prevProps, nextProps) {
/*
如果将 nextProps 传递给 render 将返回与传递 prevProps渲染相同的结果,
则返回 true ,
否则返回false
*/
}
export default React.memo(MyComponent, areEqual);
此方法仅作为 性能优化 存在。 不要依赖它来 “防止” 渲染,因为这可能导致错误。
注意
与类组件上的
shouldComponentUpdate()
方法不同,如果 props 相等,areEqual
函数返回true
,如果 props 不相等则返回false
。 这与shouldComponentUpdate
相反。
createElement()
React.createElement(
type,
[props],
[...children]
)
创建并返回一个新的给定类型的 React 元素 。这个 type(类型) 参数可以是一个标签名字字符串(例如 'div'
或'span'
),或者是一个 React 组件 类型(一个类或者是函数),或者一个 React fragment 类型。
使用 JSX 编写的代码将被转成使用 React.createElement()
。 如果你使用JSX,则你可以不必显示地直接调用 React.createElement()
。 请参阅不使用 JSX 的 React 了解更多信息。
cloneElement()
React.cloneElement(
element,
[props],
[...children]
)
使用 element
作为起点,克隆并返回一个新的 React 元素。 所产生的元素将具有原始元素的 props ,新的 props 为浅层合并。 新的子元素将取代现有的子元素, key
和 ref
将被保留。
React.cloneElement()
几乎等效于:
<element.type {...element.props} {...props}>{children}</element.type>
然而,它也会保留 ref
。这意味着,如果你通过它上面的 ref
获取自己的子节点,你将不会有机会从你的祖先获取它。你只会获得绑定在你的新元素上的相同ref
。
这个 API 引入作为废弃的 React.addons.cloneWithProps()
替代品。
createFactory()
React.createFactory(type)
返回一个函数,该函数生成给定类型的 React 元素。 像React.createElement()
一样,type(类型) 参数可以是一个标签名字字符串(例如 'div'
或'span'
),或者是一个 React 组件 类型(类或者是函数)。
参数可以是标签名称字符串(例如’div’或’span’)或者React组件类型(类或函数)。
这个函数被认为是遗留的API,并且我们鼓励你使用 JSX ,或直接使用 React.createElement()
。
如果你使用JSX,则通常不需要直接调用 React.createFactory()
。请参阅不使用 JSX 的 React 了解更多信息。
isValidElement()
React.isValidElement(object)
验证对象是否是一个 React 元素。 返回 true
或 false
。
React.Children
React.Children
提供了处理 this.props.children
这种不透明数据结构的实用程序。
React.Children.map
React.Children.map(children, function[(thisArg)])
注意
如果
children
是一个Fragment
,它将被视为一个子组件并且不会被遍历。
对包含在 children
中的每个直接子元素调用一个函数,使用 this
设置 thisArg
。 如果 children
是一个键片段(keyed fragment)或数组,它将被遍历:该函数永远不会传递容器对象(container objects)。 如果 children
为 null
或 undefined
,返回 null
或 undefined
,而不是一个数组。
React.Children.forEach
React.Children.forEach(children, function[(thisArg)])
类似于 React.Children.map()
,但是不返回一个新数组。
React.Children.count
React.Children.count(children)
返回 children
中的组件总数,等于传递给 map
或 forEach
的回调将被调用的次数。
React.Children.only
React.Children.only(children)
返回 children
中的唯一子集。否则抛出异常。
注意:
React.Children.only()
不接受React.Children.map()
的返回值,因为它是一个数组而不是一个 React 元素。
React.Children.toArray
React.Children.toArray(children)
将 children
不透明数据结构作为一个平面数组返回,并且 key 分配给每个子集。 如果你想在渲染方法中操作children集合,特别是如果你想在传递它之前重新排序或切割 this.props.children
,这将非常有用。
注意:
React.Children.toArray()
更改 keys 去防止嵌套数组的语法当扁平化子节点列表。 也就是说,toArray
为返回数组中的每个key赋予前缀,以便将每个元素的 key 范围限定为包含它的输入数组。
React.Fragment
React.Fragment
组件允许你在 render()
方法中返回多个元素,而无需创建额外的 DOM 元素:
render() {
return (
<React.Fragment>
Some text.
<h2>A heading</h2>
</React.Fragment>
);
}
你也可以用简写的 <></>
语法来使用它。 有关更多信息,请参见片段 Fragments 或者 React v16.2.0: Improved Support for Fragments。
React.createRef
React.createRef
创建一个 ref ,它可以通过 ref 属性附加到 React 元素。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
render() {
return <input type="text" ref={this.inputRef} />;
}
componentDidMount() {
this.inputRef.current.focus();
}
}
React.forwardRef
React.forwardRef
创建一个 React 组件,将它接收的 ref 属性转发给组件树中的另一个组件。这种技术并不常见,但在两种情况下特别有用:
React.forwardRef
接受渲染函数作为参数。React 将用 props
和 ref
作为两个参数来调用这个函数。此函数应返回 React 节点。
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
在上面的例子中,React 传递一个 ref
给 <FancyButton ref={ref}>
元素作为第二个参数传递给React.forwardRef
调用中的渲染函数。
该渲染函数将 ref
传递给 <button ref = {ref}>
元素。
因此,在 React 附加 ref 后,
ref.current
将直接指向 <button>
DOM 元素实例。
有关更多信息,请参阅 转发refs 。
React.lazy
React.lazy()
允许你定义动态加载的组件。 这有助于减少包大小,以延迟加载在初始渲染期间未使用的组件。
你可以从我们的 代码拆分文档 中学习如何使用它。 你还可以查看 本文 ,详细的说明了如何使用 React.lazy()
。
// This component is loaded dynamically
const SomeComponent = React.lazy(() => import('./SomeComponent'));
请注意,渲染 lazy
组件要求渲染树中有一个 <React.Suspense>
组件。这是你指定加载 indicator(指示器) 的方式。
React.Suspense
React.Suspense
允许你指定加载 indicator(指示器) ,以防下面树中的某些组件尚未准备就渲染。现在,延迟加载组件是 <React.Suspense>
支持的 唯一 用例:
// This component is loaded dynamically
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
// Displays <Spinner> until OtherComponent loads
<React.Suspense fallback={<Spinner />}>
<div>
<OtherComponent />
</div>
</React.Suspense>
);
}
它在我们的 代码拆分指南 中有记录。 请注意,lazy
组件可以位于 Suspense
树的深处 - 它不必包装它们中的每一个。 最佳做法是将 <Suspense>
放在要查看加载 indicator(指示器) 的位置,但要在任何想要进行代码拆分的地方使用 lazy()
。
虽然现在还不支持更多的用例,但未来我们计划让 Suspense
处理更多场景,例如数据获取。 你可以在 我们的路线图 中了解这一点。
注意:
ReactDOMServer
尚不支持React.lazy()
和<React.Suspense>
。这是一个已知的限制,将来会解决。