@@ -851,6 +851,12 @@ let inline fn<'P> (f: 'P -> ReactElement) (props: 'P) (children: ReactElement se
851851let inline ofImport<'P> (importMember: string) (importPath: string) (props: 'P) (children: ReactElement seq): ReactElement =
852852 createElement(import importMember importPath, props, children)
853853
854+ type ReactElementType<'props> = interface end
855+
856+ type ReactComponentType<'props> =
857+ inherit ReactElementType<'props>
858+ abstract displayName: string option with get, set
859+
854860#if FABLE_COMPILER
855861/// Alias of `ofString`
856862let inline str (s: string): ReactElement = unbox s
@@ -882,6 +888,61 @@ let inline ofArray (els: ReactElement array): ReactElement = unbox els
882888[<Emit("null")>]
883889let nothing: ReactElement = jsNative
884890
891+ [<RequireQualifiedAccess>]
892+ module ReactElementType =
893+ let inline ofComponent<'comp, 'props, 'state when 'comp :> Component<'props, 'state>> : ReactComponentType<'props> =
894+ unbox jsConstructor<'comp>
895+
896+ let inline ofFunction<'props> (f: 'props -> ReactElement) : ReactComponentType<'props> =
897+ unbox f
898+
899+ let inline ofHtmlElement<'props> (name: string): ReactElementType<'props> =
900+ unbox name
901+
902+ /// Create a ReactElement to be rendered from an element type, props and children
903+ let inline create<'props> (comp: ReactElementType<'props>) (props: 'props) (children: ReactElement seq): ReactElement =
904+ createElement(comp, props, children)
905+
906+ type PropsEqualityComparison<'props> = 'props -> 'props -> bool
907+
908+ [<Import("memo", from="react")>]
909+ let private reactMemo<'props> (render: 'props -> ReactElement) : ReactComponentType<'props> =
910+ jsNative
911+
912+ /// React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of
913+ /// classes.
914+ ///
915+ /// If your function component renders the same result given the same props, you can wrap it in a call to React.memo
916+ /// for a performance boost in some cases by memoizing the result. This means that React will skip rendering the
917+ /// component, and reuse the last rendered result.
918+ ///
919+ /// By default it will only shallowly compare complex objects in the props object. If you want control over the
920+ /// comparison, you can use `memoWith`.
921+ let memo<'props> (name: string) (render: 'props -> ReactElement) : ReactComponentType<'props> =
922+ render?displayName <- name
923+ reactMemo(render)
924+
925+ [<Import("memo", from="react")>]
926+ let private reactMemoWith<'props> (render: 'props -> ReactElement, areEqual: PropsEqualityComparison<'props>) : ReactComponentType<'props> =
927+ jsNative
928+
929+ /// React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of
930+ /// classes.
931+ ///
932+ /// If your function component renders the same result given the same props, you can wrap it in a call to React.memo
933+ /// for a performance boost in some cases by memoizing the result. This means that React will skip rendering the
934+ /// component, and reuse the last rendered result.
935+ ///
936+ /// This version allow you to control the comparison used instead of the default shallow one by provide a custom
937+ /// comparison function.
938+ let memoWith<'props> (name: string) (areEqual: PropsEqualityComparison<'props>) (render: 'props -> ReactElement) : ReactComponentType<'props> =
939+ render?displayName <- name
940+ reactMemoWith(render, areEqual)
941+
942+ /// Create a ReactElement to be rendered from an element type, props and children
943+ let inline ofElementType<'props> (comp: ReactElementType<'props>) (props: 'props) (children: ReactElement seq): ReactElement =
944+ ReactElementType.create comp props children
945+
885946#else
886947/// Alias of `ofString`
887948let inline str (s: string): ReactElement = HTMLNode.Text s :> ReactElement
0 commit comments