[react] [react-dom] Add support for rendering an array of elements (#19363)

* Test

* Fix react typings

* Revert "Use []-syntax for some cases."

This reverts commit 5f6e55843980b2cff9ace4174f72b4f8aa7ad278.

* Modify another render function's return type

* Use Array<T> instead in react.d.ts & Fix issues with the typescript linter & Adapt changes in react-router

* Convert Array<T> to T[]

* Add support for string and number return types.
This commit is contained in:
cynecx
2017-10-06 20:08:29 +02:00
committed by John Reilly
parent 66feddd421
commit 0b21b7dd63
4 changed files with 52 additions and 19 deletions

View File

@@ -15,7 +15,6 @@ import {
DOMAttributes, DOMElement
} from 'react';
export function findDOMNode<E extends Element>(instance: ReactInstance): E;
export function findDOMNode(instance: ReactInstance): Element;
export function unmountComponentAtNode(container: Element): boolean;
@@ -27,9 +26,9 @@ export function unstable_batchedUpdates<A, B>(callback: (a: A, b: B) => any, a:
export function unstable_batchedUpdates<A>(callback: (a: A) => any, a: A): void;
export function unstable_batchedUpdates(callback: () => any): void;
export function unstable_renderSubtreeIntoContainer<P extends DOMAttributes<T>, T extends Element>(
export function unstable_renderSubtreeIntoContainer<T extends Element>(
parentComponent: Component<any>,
element: DOMElement<P, T>,
element: DOMElement<DOMAttributes<T>, T>,
container: Element,
callback?: (element: T) => any): T;
export function unstable_renderSubtreeIntoContainer<P, T extends Component<P, ComponentState>>(
@@ -44,30 +43,55 @@ export function unstable_renderSubtreeIntoContainer<P>(
callback?: (component?: Component<P, ComponentState> | Element) => any): Component<P, ComponentState> | Element | void;
export interface Renderer {
<P extends DOMAttributes<T>, T extends Element>(
element: DOMElement<P, T>,
// Deprecated(render): The return value is deprecated.
// In future releases the render function's return type will be void.
<T extends Element>(
element: DOMElement<DOMAttributes<T>, T>,
container: Element | null,
callback?: (element: T) => any
callback?: () => void
): T;
<P>(
element: SFCElement<P>,
(
element: Array<DOMElement<DOMAttributes<any>, any>>,
container: Element | null,
callback?: () => any
callback?: () => void
): Element;
(
element: SFCElement<any> | Array<SFCElement<any>>,
container: Element | null,
callback?: () => void
): void;
<P, T extends Component<P, ComponentState>>(
element: CElement<P, T>,
container: Element | null,
callback?: (component: T) => any
callback?: () => void
): T;
(
element: Array<CElement<any, Component<any, ComponentState>>>,
container: Element | null,
callback?: () => void
): Component<any, ComponentState>;
<P>(
element: ReactElement<P>,
container: Element | null,
callback?: (component?: Component<P, ComponentState> | Element) => any
callback?: () => void
): Component<P, ComponentState> | Element | void;
<P>(
parentComponent: Component<any>,
element: SFCElement<P>,
(
element: Array<ReactElement<any>>,
container: Element | null,
callback?: () => void
): Component<any, ComponentState> | Element | void;
(
parentComponent: Component<any> | Array<Component<any>>,
element: SFCElement<any>,
container: Element,
callback?: () => any
callback?: () => void
): void;
}

View File

@@ -10,7 +10,9 @@ interface CustomRouteInterface extends RouteProps {
// React advocates composition over inheritance, but doesn't prevent us from using it
export default class CustomRoute extends Route<CustomRouteInterface> {
render() {
const maybeElement = super.render();
// react-fiber's render function can also return an array of elements,
// but in this case it's assumed that a JSX.Element is returned.
const maybeElement = super.render() as JSX.Element;
return maybeElement && <div className="meaningfulClass">{React.cloneElement(maybeElement, this.props)}</div>;
}
}

View File

@@ -284,7 +284,7 @@ declare namespace React {
// tslint:enable:unified-signatures
forceUpdate(callBack?: () => any): void;
render(): JSX.Element | null | false;
render(): JSX.Element | JSX.Element[] | string | number | null | false;
// React.Props<T> is now deprecated, which means that the `children`
// property is not available on `P` by default, even though you can
@@ -419,7 +419,7 @@ declare namespace React {
}
interface ComponentSpec<P, S> extends Mixin<P, S> {
render(): ReactElement<any> | null;
render(): ReactElement<any> | Array<ReactElement<any>> | string | number | null;
[propertyName: string]: any;
}
@@ -3453,7 +3453,7 @@ declare global {
// tslint:disable:no-empty-interface
interface Element extends React.ReactElement<any> { }
interface ElementClass extends React.Component<any> {
render(): Element | null | false;
render(): Element | Element[] | string | number | null | false;
}
interface ElementAttributesProperty { props: {}; }
interface ElementChildrenAttribute { children: {}; }

View File

@@ -129,6 +129,13 @@ class ModernComponent extends React.Component<Props, State>
}
}
class ModernComponentArrayRender extends React.Component<Props> {
render() {
return [React.DOM.h1({ key: "1" }, "1"),
React.DOM.h1({ key: "2" }, "2")];
}
}
class ModernComponentNoState extends React.Component<Props> { }
class ModernComponentNoPropsAndState extends React.Component { }