@@ -888,6 +888,8 @@ let inline ofArray (els: ReactElement array): ReactElement = unbox els
888888[<Emit("null")>]
889889let nothing: ReactElement = jsNative
890890
891+ type PropsEqualityComparison<'props> = 'props -> 'props -> bool
892+
891893[<RequireQualifiedAccess>]
892894module ReactElementType =
893895 let inline ofComponent<'comp, 'props, 'state when 'comp :> Component<'props, 'state>> : ReactComponentType<'props> =
@@ -903,45 +905,82 @@ module ReactElementType =
903905 let inline create<'props> (comp: ReactElementType<'props>) (props: 'props) (children: ReactElement seq): ReactElement =
904906 createElement(comp, props, children)
905907
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.
908+ /// React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of
909+ /// classes.
910+ ///
911+ /// If your function component renders the same result given the same props, you can wrap it in a call to React.memo
912+ /// for a performance boost in some cases by memoizing the result. This means that React will skip rendering the
913+ /// component, and reuse the last rendered result.
914+ ///
915+ /// By default it will only shallowly compare complex objects in the props object. If you want control over the
916+ /// comparison, you can use `memoWith`.
917+ [<Import("memo", from="react")>]
918+ let inline memo<'props> (render: 'props -> ReactElement) : ReactComponentType<'props> =
919+ jsNative
920+
921+ [<Import("memo", from="react")>]
922+ let private reactMemoWith<'props> (render: 'props -> ReactElement, areEqual: PropsEqualityComparison<'props>) : ReactComponentType<'props> =
923+ jsNative
924+
925+ /// React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of
926+ /// classes.
927+ ///
928+ /// If your function component renders the same result given the same props, you can wrap it in a call to React.memo
929+ /// for a performance boost in some cases by memoizing the result. This means that React will skip rendering the
930+ /// component, and reuse the last rendered result.
931+ ///
932+ /// This version allow you to control the comparison used instead of the default shallow one by provide a custom
933+ /// comparison function.
934+ let memoWith<'props> (areEqual: PropsEqualityComparison<'props>) (render: 'props -> ReactElement) : ReactComponentType<'props> =
935+ reactMemoWith(render, areEqual)
936+
937+ /// memo is similar to React.PureComponent but is built from only a render function.
914938///
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.
939+ ///
940+ /// If your function renders the same result given the same props, you can wrap it in a call to memo for a performance
941+ /// boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the
942+ /// last rendered result.
943+ ///
944+ /// The resulting function shouldn't be used directly in a render but should be stored to be reused :
945+ ///
946+ /// ```
947+ /// type HelloProps = { Name: string }
948+ /// let hello = memo "Hello" (fun { Name = name } -> span [str "Hello "; str name])
949+ ///
950+ /// let view model =
951+ /// hello { Name = model.Name }
952+ /// ```
918953///
919954/// By default it will only shallowly compare complex objects in the props object. If you want control over the
920955/// comparison, you can use `memoWith`.
921- let memo<'props> (name: string) (render: 'props -> ReactElement) : ReactComponentType< 'props> =
956+ let memo<'props> (name: string) (render: 'props -> ReactElement) : 'props -> ReactElement =
922957 render?displayName <- name
923- reactMemo(render)
958+ let memoType = ReactElementType.memo render
959+ fun props ->
960+ ReactElementType.create memoType props []
924961
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 .
962+ /// memoWith is similar to React.Component but is built from a render function and an equality
963+ /// (Inverse of shouldComponentUpdate) function.
964+ ///
965+ /// If your function renders the same result given the "same" props (According to areEqual), you can wrap it in a call
966+ /// to memoWith for a performance boost in some cases by memoizing the result. This means that React will skip rendering
967+ /// the component, and reuse the last rendered result .
931968///
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.
969+ /// The resulting function shouldn't be used directly in a render but should be stored to be reused :
935970///
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> =
971+ /// ```
972+ /// type HelloProps = { Name: string }
973+ /// let helloEquals p1 p2 = p1.Name = p2.Name
974+ /// let hello = memoWith "Hello" helloEquals (fun { Name = name } -> span [str "Hello "; str name])
975+ ///
976+ /// let view model =
977+ /// hello { Name = model.Name }
978+ /// ```
979+ let memoWith<'props> (name: string) (areEqual: PropsEqualityComparison<'props>) (render: 'props -> ReactElement) : 'props -> ReactElement =
939980 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
981+ let memoType = ReactElementType.memoWith areEqual render
982+ fun props ->
983+ ReactElementType.create memoType props []
945984
946985#else
947986/// Alias of `ofString`
0 commit comments