You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.8 KiB
170 lines
4.8 KiB
package com.example.playscalajsreact.component
|
|
|
|
import com.example.playscalajsreact.model.MyGlobalState
|
|
import japgolly.scalajs.react.vdom.VdomElement
|
|
import japgolly.scalajs.react._
|
|
import japgolly.scalajs.react.vdom.html_<^._
|
|
import com.example.playscalajsreact.route.AppRouter
|
|
import com.example.playscalajsreact.model.User
|
|
import japgolly.scalajs.react.extra.StateSnapshot
|
|
// import com.softwaremill.quicklens._
|
|
import com.example.playscalajsreact.model._
|
|
|
|
object Top {
|
|
|
|
final class Backend($ : BackendScope[Unit, Data]) {
|
|
private val setStateFn =
|
|
StateSnapshot.withReuse.prepareVia($)
|
|
|
|
def render(state: Data): VdomElement = {
|
|
val ss = setStateFn(state)
|
|
// Middle.Props("Demo", ss).render
|
|
Middle(Middle.Props("Demo", ss))
|
|
}
|
|
}
|
|
|
|
val Comp = ScalaComponent
|
|
.builder[Unit]
|
|
.initialState(Data(123, "hello"))
|
|
.renderBackend[Backend]
|
|
.build
|
|
}
|
|
|
|
object Top2 {
|
|
import japgolly.scalajs.react.vdom.all._
|
|
import japgolly.scalajs.react.MonocleReact._
|
|
|
|
final class Backend($ : BackendScope[Unit, MyGlobalState]) {
|
|
private val setStateFn =
|
|
StateSnapshot.withReuse.prepareVia($)
|
|
|
|
def render(state: MyGlobalState): VdomElement = {
|
|
// val ss = StateSnapshot.zoomL(MyGlobalState.user)(state).setStateVia($)
|
|
|
|
// val ss2 = ss.xmapState(u => Snappy.State(u))(_.user)
|
|
// div(Snappy.Props(ss2).render)
|
|
val ss = setStateFn(state)
|
|
|
|
div(
|
|
// Middle2.Props("Middle2", ss).render,
|
|
AppRouter.router(AppRouter.Props(ss)),
|
|
"Value: ",
|
|
state.user.map(_.username)
|
|
)
|
|
}
|
|
}
|
|
|
|
val Top2Component = ScalaComponent
|
|
.builder[Unit]("Top2")
|
|
.initialState(MyGlobalState(Some(User("testuser"))))
|
|
// .initialState(MyGlobalState.empty)
|
|
.renderBackend[Backend]
|
|
.build
|
|
|
|
def apply(): VdomElement = Top2Component()
|
|
}
|
|
|
|
object Middle2 {
|
|
import japgolly.scalajs.react.MonocleReact._
|
|
import monocle.macros.syntax.lens._
|
|
import monocle.std.option._
|
|
import monocle.macros.GenIso
|
|
import cats.implicits._
|
|
|
|
// val navigateToUsername = GenIso[MyGlobalState, Option[User]]
|
|
// .composePrism(GenIso[User, String].asPrism.below[Option])
|
|
|
|
val navigateToUsername =
|
|
MyGlobalState.user.composePrism(GenIso[User, String].asPrism.below[Option])
|
|
|
|
final case class Props(name: String, ss: StateSnapshot[MyGlobalState]) {
|
|
@inline def render: VdomElement = Comp(this)
|
|
}
|
|
|
|
implicit def reusability: Reusability[Props] =
|
|
Reusability.derive
|
|
|
|
final class Backend($ : BackendScope[Props, Unit]) {
|
|
|
|
// Method 2: StateSnapshot.withReuse.zoomL.prepareViaProps
|
|
// Notice that we're using a normal lens here instead of a Reusable[lens]
|
|
private val ssStrFn =
|
|
StateSnapshot.withReuse.zoomL(MyGlobalState.user).prepareViaProps($)(_.ss)
|
|
|
|
def render(p: Props): VdomElement = {
|
|
val x = p.ss.zoomStateO(navigateToUsername)
|
|
val y = x.map(_.xmapState(_ => 1)(_ => None))
|
|
|
|
// Method 1: ss.withReuse.zoomStateL
|
|
// val ssI: StateSnapshot[Int] = p.ss.zoomStateL(Data.reusableLens.int)
|
|
|
|
// Method 2: StateSnapshot.withReuse.zoomL.prepareViaProps
|
|
// val ssS: StateSnapshot[String] =
|
|
// ssStrFn(p.ss.value)
|
|
|
|
val ss4 = p.ss.zoomStateL(MyGlobalState.user)
|
|
// val ss5 = p.ss.zoomStateO(navigateToUsername.asOptional)
|
|
// val ss6 =
|
|
// ss5.map(_.xmapState(_.map(n => User(n)))(_.map(u => u.username)))
|
|
// ss5.foreach(_.modState(e => e))
|
|
// val x = p.ss.value.lens(_.user.getOrElse(User.empty).username)
|
|
// p.ss.zoomStateO()
|
|
|
|
val ss2 = ss4.xmapState(u => Snappy.State(u))(_.user)
|
|
|
|
<.div(
|
|
<.h3(p.name),
|
|
<.div("Snappy", Snappy.Props(ss2).render)
|
|
)
|
|
}
|
|
}
|
|
|
|
val Comp = ScalaComponent
|
|
.builder[Props]
|
|
.renderBackend[Backend]
|
|
// .configure(Reusability.shouldComponentUpdate)
|
|
.build
|
|
|
|
def apply(_props: Props): VdomElement = { Comp(_props) }
|
|
}
|
|
|
|
object Snappy {
|
|
|
|
final case class Props(state: StateSnapshot[State]) {
|
|
@inline def render: VdomElement = Component(this)
|
|
}
|
|
|
|
//implicit val reusabilityProps: Reusability[Props] =
|
|
// Reusability.derive
|
|
|
|
final case class State(user: Option[User])
|
|
|
|
object State {
|
|
def empty = State(user = None)
|
|
|
|
//implicit val reusability: Reusability[State] =
|
|
// Reusability.derive
|
|
}
|
|
|
|
final class Backend($ : BackendScope[Props, Unit]) {
|
|
import com.softwaremill.quicklens._
|
|
def render(p: Props): VdomNode = {
|
|
val s = p.state.value
|
|
<.div("Test", s.user.map(u => {
|
|
<.div(
|
|
"Username",
|
|
u.username,
|
|
^.onClick --> p.state.modState(
|
|
_.modify(_.user.each.username).using(_ + "c")
|
|
)
|
|
)
|
|
}))
|
|
}
|
|
}
|
|
|
|
val Component = ScalaComponent
|
|
.builder[Props]("Snappy")
|
|
.renderBackend[Backend]
|
|
//.configure(Reusability.shouldComponentUpdate)
|
|
.build
|
|
}
|