|
1 | 1 | package japgolly.scalajs.react.hooks |
2 | 2 |
|
3 | 3 | import japgolly.microlibs.types.NaturalComposition |
4 | | -import japgolly.scalajs.react.internal.ShouldComponentUpdateComponent |
| 4 | +import japgolly.scalajs.react.internal.CoreGeneral.ScalaFnComponent |
5 | 5 | import japgolly.scalajs.react.util.DefaultEffects |
6 | 6 | import japgolly.scalajs.react.vdom.VdomNode |
7 | | -import japgolly.scalajs.react.{PropsChildren, Reusability, Reusable} |
| 7 | +import japgolly.scalajs.react.{PropsChildren, React, Reusability, Reusable} |
8 | 8 |
|
9 | 9 | final class CustomHook[I, O] private[CustomHook] (val unsafeInit: I => O) extends AnyVal { |
10 | 10 |
|
@@ -206,9 +206,21 @@ object CustomHook { |
206 | 206 | def reusableByDeps[D, A](create: (D, Int) => A)(implicit r: Reusability[D]): CustomHook[() => D, Reusable[A]] = |
207 | 207 | reusableDeps[D].map { case (d, rev) => Reusable.implicitly(rev).withValue(create(d, rev)) } |
208 | 208 |
|
209 | | - def shouldComponentUpdate[D](render: D => VdomNode)(implicit r: Reusability[D]): CustomHook[() => D, VdomNode] = |
210 | | - reusableDeps[D].map { case (d, rev) => |
211 | | - ShouldComponentUpdateComponent(rev, () => render(d)) |
| 209 | + protected[hooks] final case class ReuseComponentProps[A](value: A, render: A => VdomNode)(implicit val reusability: Reusability[A]) { |
| 210 | + def renderVdom: VdomNode = render(value) |
| 211 | + } |
| 212 | + |
| 213 | + private implicit val reusabilityInstance: Reusability[ReuseComponentProps[Any]] = |
| 214 | + Reusability( (a, b) => a.reusability.test(a.value, b.value) ) |
| 215 | + |
| 216 | + // Component for reuse. Must be stable. |
| 217 | + private val ReuseComponent = React.memo(ScalaFnComponent[ReuseComponentProps[Any]](_.renderVdom)) |
| 218 | + |
| 219 | + def shouldComponentUpdate[D](render: D => VdomNode)(implicit r: Reusability[D]): CustomHook[() => D, VdomNode] = { |
| 220 | + CustomHook[() => D] |
| 221 | + .buildReturning{ deps => |
| 222 | + ReuseComponent(ReuseComponentProps(deps(), render).asInstanceOf[ReuseComponentProps[Any]] ) |
| 223 | + } |
212 | 224 | } |
213 | 225 |
|
214 | 226 | lazy val useForceUpdate: CustomHook[Unit, Reusable[DefaultEffects.Sync[Unit]]] = { |
|
0 commit comments