xyhthink

React 是 React 库的入口。如果你通过使用 <script> 标签的方式来加载 React,则可以通过 React 全局变量对象来获得 React 的顶层 API。当你使用 ES6 与 npm 时,可以通过编写 import React from 'react' 来引入它们。当你使用 ES5 与 npm 时,则可以通过编写 var React = require('react') 来引入它们。

React 顶层 API

React.Component

React.Component 是使用 ES6 classes 方式定义 React 组件的基类:

1
2
3
4
5
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

React.PureComponent

React.PureComponentReact.Component 很相似。两者的区别在于 React.Component并未实现 shouldComponentUpdate(),而 React.PureComponent 中以浅层对比 prop 和 state 的方式来实现了该函数。

如果赋予 React 组件相同的 props 和 state,render() 函数会渲染相同的内容,那么在某些情况下使用 React.PureComponent 可提高性能。

注意

React.PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的 props 和 state 较为简单时,才使用 React.PureComponent,或者在深层数据结构发生变化时调用 forceUpdate() 来确保组件被正确地更新。你也可以考虑使用 immutable 对象加速嵌套数据的比较。

此外,React.PureComponent 中的 shouldComponentUpdate() 将跳过所有子组件树的 prop 更新。因此,请确保所有子组件也都是“纯”的组件。

##React.memo

1
2
3
const MyComponent = React.memo(function MyComponent(props) {
/* 使用 props 渲染 */
});

eact.memo高阶组件。它与 React.PureComponent 非常相似,但它适用于函数组件,但不适用于 class 组件。

如果你的函数组件在给定相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。

默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。

1
2
3
4
5
6
7
8
9
10
11
function MyComponent(props) {
/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
/*
如果把 nextProps 传入 render 方法的返回结果与
将 prevProps 传入 render 方法的返回结果一致则返回 true,
否则返回 false
*/
}
export default React.memo(MyComponent, areEqual);

此方法仅作为性能优化的方式而存在。但请不要依赖它来“阻止”渲染,因为这会产生 bug。

注意

与 class 组件中 shouldComponentUpdate() 方法不同的是,如果 props 相等,areEqual 会返回 true;如果 props 不相等,则返回 false。这与 shouldComponentUpdate 方法的返回值相反。

createElement()

1
2
3
4
5
React.createElement(
type,
[props],
[...children]
)

创建并返回指定类型的新 React 元素。其中的类型参数既可以是标签名字符串(如 'div''span'),也可以是 React 组件 类型 (class 组件或函数组件),或是 React fragment 类型。

使用 JSX 编写的代码将会被转换成使用 React.createElement() 的形式。如果使用了 JSX 方式,那么一般来说就不需要直接调用 React.createElement()

cloneElement()

1
2
3
4
5
React.cloneElement(
element,
[props],
[...children]
)

element 元素为样板克隆并返回新的 React 元素。返回元素的 props 是将新的 props 与原始元素的 props 浅层合并后的结果。新的子元素将取代现有的子元素,而来自原始元素的 keyref 将被保留。

React.cloneElement() 几乎等同于:

1
<element.type {...element.props} {...props}>{children}</element.type>

但是,这也保留了组件的 ref。这意味着当通过 ref 获取子节点时,你将不会意外地从你祖先节点上窃取它。相同的 ref 将添加到克隆后的新元素中。

引入此 API 是为了替换已弃用的 React.addons.cloneWithProps()

createFactory()

1
React.createFactory(type)

返回用于生成指定类型 React 元素的函数。与 React.createElement() 相似的是,类型参数既可以是标签名字符串(像是 'div''span'),也可以是 React 组件 类型 (class 组件或函数组件),或是 React fragment 类型。

此辅助函数已废弃,建议使用 JSX 或直接调用 React.createElement() 来替代它。

isValidElement()

1
React.isValidElement(object)

验证对象是否为 React 元素,返回值为 truefalse

React.Children

React.Children 提供了用于处理 this.props.children 不透明数据结构的实用方法。

React.Children.map

1
React.Children.map(children, function[(thisArg)])

children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg。如果 children 是一个数组,它将被遍历并为数组中的每个子节点调用该函数。如果子节点为 null 或是 undefined,则此方法将返回 null 或是 undefined,而不会返回数组。

注意

如果 children 是一个 Fragment 对象,它将被视为单一子节点的情况处理,而不会被遍历。

React.Children.forEach

1
React.Children.forEach(children, function[(thisArg)])

React.Children.map() 类似,但它不会返回一个数组。

React.Children.count

1
React.Children.count(children)

返回 children 中的组件总数量,等同于通过 mapforEach 调用回调函数的次数。

React.Children.only

1
React.Children.only(children)

验证 children 是否只有一个子节点(一个 React 元素),如果有则返回它,否则此方法会抛出错误。

React.Children.toArray

1
React.Children.toArray(children)

children 这个复杂的数据结构以数组的方式扁平展开并返回,并为每个子节点分配一个 key。当你想要在渲染函数中操作子节点的集合时,它会非常实用,特别是当你想要在向下传递 this.props.children 之前对内容重新排序或获取子集时。

React.Fragment

React.Fragment 组件能够在不额外创建 DOM 元素的情况下,让 render() 方法中返回多个元素。

1
2
3
4
5
6
7
8
render() {
return (
<React.Fragment>
Some text.
<h2>A heading</h2>
</React.Fragment>
);
}

你也可以使用其简写语法 <></>

React.createRef

React.createRef 创建一个能够通过 ref 属性附加到 React 元素的 ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 将使用 propsref 作为参数来调用此函数。此函数应返回 React 节点。

1
2
3
4
5
6
7
8
9
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 会将 <FancyButton ref={ref}> 元素的 ref 作为第二个参数传递给 React.forwardRef 函数中的渲染函数。该渲染函数会将 ref 传递给 <button ref={ref}> 元素。

因此,当 React 附加了 ref 属性之后,ref.current 将直接指向 <button> DOM 元素实例。

React.lazy

React.lazy() 允许你定义一个动态加载的组件。这有助于缩减 bundle 的体积,并延迟加载在初次渲染时未用到的组件。

1
2
// 这个组件是动态加载的
const SomeComponent = React.lazy(() => import('./SomeComponent'));

请注意,渲染 lazy 组件依赖该组件渲染树上层的 <React.Suspense> 组件。这是指定加载指示器(loading indicator)的方式。

注意

使用 React.lazy 的动态引入特性需要 JS 环境支持 Promise。在 IE11 及以下版本的浏览器中需要通过引入 polyfill 来使用该特性。

React.Suspense

React.Suspense 可以指定加载指示器(loading indicator),以防其组件树中的某些子组件尚未具备渲染条件。目前,懒加载组件是 <React.Suspense> 支持的唯一用例:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 该组件是动态加载的
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
// 显示 <Spinner> 组件直至 OtherComponent 加载完成
<React.Suspense fallback={<Spinner />}>
<div>
<OtherComponent />
</div>
</React.Suspense>
);
}

请注意,lazy 组件可以位于 Suspense 组件树的深处——它不必包装树中的每一个延迟加载组件。最佳实践是将 <Suspense> 置于你想展示加载指示器(loading indicator)的位置,而 lazy() 则可被放置于任何你想要做代码分割的地方。

虽然目前尚未支持其它特性,但未来我们计划让 Suspense 支持包括数据获取在内的更多场景。你可以在 roadmap 中了解相关信息。

注意:

React.lazy()<React.Suspense> 尚未在 ReactDOMServer 中支持。这是已知问题,将会在未来解决。

 评论


Power by Yuhangxie , 总访问量为 次 。
载入天数...载入时分秒...
京ICP备19024986号