Skip to content

Commit cb824f1

Browse files
committed
Lifting State Up
1 parent d59c31f commit cb824f1

File tree

1 file changed

+58
-37
lines changed

1 file changed

+58
-37
lines changed

react_learn/src/main/scala/tutorial/webapp/TutorialApp.scala

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,60 +6,81 @@ import org.scalajs.dom
66

77

88
object Square {
9-
case class State(value: String="")
9+
case class Props(value:String, onClick:Callback)
1010

11-
class Backend(bs: BackendScope[Unit, State]) {
11+
class Backend(bs: BackendScope[Props, Unit]) {
1212

13-
def render(state: State) =
13+
def render(props: Props) = {
1414
<.button(
1515
^.cls := "square",
16-
^.onClick --> bs.setState(State("X")),
17-
state.value
16+
^.onClick --> props.onClick,
17+
props.value
1818
)
19+
}
1920
}
2021

21-
val component = ScalaComponent.builder[Unit]("Square")
22-
.initialState(State())
22+
val component = ScalaComponent.builder[Props]("Square")
2323
.renderBackend[Backend]
2424
.build
2525

26-
def apply(i: Int) = component()
26+
def apply(value: Option[String], onClick: Callback) = component(
27+
Props(
28+
value.getOrElse(""),
29+
onClick
30+
)
31+
)
2732
}
2833

2934

3035
object Board {
31-
def renderSquare(i: Int) = Square(i)
3236

33-
val component = ScalaComponent.builder[Unit]("Board")
34-
.renderStatic(
35-
{
36-
val status = "Next player: X"
37+
case class State(
38+
square:List[Option[String]],
39+
)
40+
41+
class Backend(bs: BackendScope[Unit, State]) {
42+
43+
def render(state: State) = {
44+
val status = "Next player: X"
45+
<.div(
46+
<.div(
47+
^.cls := "status",
48+
status
49+
),
50+
<.div(
51+
^.cls := "board-row",
52+
renderSquare(state, 0),
53+
renderSquare(state, 1),
54+
renderSquare(state, 2)
55+
),
56+
<.div(
57+
^.cls := "board-row",
58+
renderSquare(state, 3),
59+
renderSquare(state, 4),
60+
renderSquare(state, 5)
61+
),
3762
<.div(
38-
<.div(
39-
^.cls := "status",
40-
status,
41-
),
42-
<.div(
43-
^.cls := "board-row",
44-
renderSquare(0),
45-
renderSquare(1),
46-
renderSquare(2)
47-
),
48-
<.div(
49-
^.cls := "board-row",
50-
renderSquare(3),
51-
renderSquare(4),
52-
renderSquare(5)
53-
),
54-
<.div(
55-
^.cls := "board-row",
56-
renderSquare(6),
57-
renderSquare(7),
58-
renderSquare(8)
59-
)
63+
^.cls := "board-row",
64+
renderSquare(state, 6),
65+
renderSquare(state, 7),
66+
renderSquare(state, 8)
6067
)
61-
}
62-
)
68+
)
69+
}
70+
71+
def renderSquare(state: State, i: Int) = {
72+
Square(
73+
state.square(i),
74+
handleClick(i)
75+
)
76+
}
77+
78+
def handleClick(i: Int) = bs.modState(s => s.copy(square=s.square.updated(i, Some("X"))))
79+
}
80+
81+
val component = ScalaComponent.builder[Unit]("Board")
82+
.initialState(State(List.fill(9)(None)))
83+
.renderBackend[Backend]
6384
.build
6485

6586
def apply() = component()

0 commit comments

Comments
 (0)