@@ -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