01. React.forwardRef < P:props , T:ref >
一. interface React.ForwardRefExoticComponent
interface ExoticComponent<P = {}> {
/**
* **NOTE**: Exotic components are not callable.
*/
(props: P): (ReactElement|null);
readonly $$typeof: symbol;
}
interface NamedExoticComponent<P = {}> extends ExoticComponent<P> {
displayName?: string;
}
interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> {
defaultProps?: Partial<P>;
propTypes?: WeakValidationMap<P>;
}
function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>):ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
// render 参数
interface ForwardRefRenderFunction<T, P = {}> {
/**
* PropsWithChildren<P>
* ref: ForwardedRef<T>
* Function (a: any, value: T): Array<T>; InternalButton === render
*/
(props: PropsWithChildren<P>, ref: ForwardedRef<T>): ReactElement | null;
displayName?: string;
// explicit rejected with `never` required due to
// https://github.com/microsoft/TypeScript/issues/36826
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never;
/**
* propTypes are not supported on render functions
*/
propTypes?: never;
}
// ======== return ======= //
interface ForwardRefExoticComponent<P> {
/**
* **NOTE**: Exotic components are not callable.
* React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLElement>>
*/
(props: P): (ReactElement|null); // React.RefAttributes<HTMLElement>
readonly $$typeof: symbol;
displayName?: string;
defaultProps?: Partial<P>;
propTypes?: WeakValidationMap<P>;
}
02. React.Children
React.Children 提供了用于处理 this.props.children 不透明数据结构的实用方法。
一. React.Children.map
React.Children.map(children, function[(thisArg)])
在 children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg。如果 children 是一个数组,它将被遍历并为数组中的每个子节点调用该函数。如果子节点为 null 或是 undefined,则此方法将返回 null 或是 undefined,而不会返回数组。
注意:如果 children 是一个 Fragment 对象,它将被视为单一子节点的情况处理,而不会被遍历。
二. React.Children.forEach
与 React.Children.map() 类似,但它不会返回一个数组。
React.Children.forEach(children, function[(thisArg)])
三. React.Children.count
返回 children 中的组件总数量,等同于通过 map 或 forEach 调用回调函数的次数。
React.Children.count(children)
四. React.Children.only
验证 children 是否只有一个子节点(一个 React 元素),如果有则返回它,否则此方法会抛出错误。
React.Children.only(children)
React.Children.only() 不接受 React.Children.map() 的返回值,因为它是一个数组而并不是 React 元素。
五. React.Children.toArray
将 children 这个复杂的数据结构以数组的方式扁平展开并返回,并为每个子节点分配一个 key。当你想要在渲染函数中操作子节点的集合时,它会非常实用,特别是当你想要在向下传递 this.props.children 之前对内容重新排序或获取子集时。
React.Children.toArray(children)
React.Children.toArray() 在拉平展开子节点列表时,更改 key 值以保留嵌套数组的语义。也就是说,toArray 会为返回数组中的每个 key 添加前缀,以使得每个元素 key 的范围都限定在此函数入参数组的对象内
03. React.Fragment
React.Fragment 组件能够在不额外创建 DOM 元素的情况下,让 render() 方法中返回多个元素。
render() {
return (
<React.Fragment>
Some text.
<h2>A heading</h2>
</React.Fragment>
);
}
你也可以使用其简写语法 <></>。欲了解更多相关信息,请参阅 React v16.2.0: Fragments 支持改进。
04.cloneElement()
以 element 元素为样板克隆并返回新的 React 元素。返回元素的 props 是将新的 props 与原始元素的 props 浅层合并后的结果。新的子元素将取代现有的子元素,而来自原始元素的 key 和 ref 将被保留
React.cloneElement(
element,
[props],
[...children]
)
// ======> 等同于//
<element.type {...element.props} {...props}>{children}</element.type>
但是,这也保留了组件的 ref。这意味着当通过 ref 获取子节点时,你将不会意外地从你祖先节点上窃取它。相同的 ref 将添加到克隆后的新元素中。
引入此 API 是为了替换已弃用的 React.addons.cloneWithProps()。
05. React.FunctionComponent (React.F C)
FunctionComponent 既可以当作函数调用,同时又能定义 defaultProps displayName 等固定属性。
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
// props?.children = null
type PropsWithChildren<P> = P & { children?: ReactNode };
import React, { FC } from 'react';
/**
* 声明Props类型
*/
export interface MyComponentProps {
className?: string;
style?: React.CSSProperties;
}
export const MyComponent: FC<MyComponentProps> = props => {
return <div>hello react</div>;
};
等同于
export interface MyComponentProps {
className?: string;
style?: React.CSSProperties;
// 手动声明children
children?: React.ReactNode;
}
export function MyComponent(props: MyComponentProps) {
return <div>hello react</div>;
}
// 导出的模式
export default function Foo(props: {}) {
return <div>xxx</div>;
}