こちらの続きです。
FletでReactチュートリアルを真似る5 - C#ATIA
Stateのリフトアップです。
チュートリアル:React の導入 – React
SquareクラスのコンストラクタでStateを受け取る様にしました。
class Square(ft.UserControl): def __init__(self, state: State): super().__init__(self) self.state = state ・・・
BoardクラスではNoneで初期化されたStateを9個用意し、Squareの
インスタンス作成時のパラメータとして渡します。
class Board(ft.UserControl): def __init__(self): super().__init__(self) self.state = { 'squares': State(None) * 9 } def renderSquare(self, i): return Square( self.state['square'][i] ) ・・・
これで、上流側のBoardクラスのself.stateで状態を管理し、
Squareクラスでは状態を管理しなくなりました。・・・多分。
現在はクリックした際に”X”しか表示していませんが、偶数回目の
クリックでは”O”を表示させます。その為、何を表示させるかを
上流側のBoardクラスから指示してやります。って事ですよね?
チュートリアルではクリックイベントハンドラを渡しています。
Squareクラスのクリックイベントハンドラを、そのままBoard
クラスに移動させ、インスタンス生成時にハンドラを渡しました。
class Board(ft.UserControl): ・・・ def renderSquare(self, i): return Square( self.state['square'][i], self.on_click_handler, ) def on_click_handler(self, e): self.state.set('X') ・・・
Squareクラスでは受け取ったハンドラをそのまま実装。
class Square(ft.UserControl): def __init__(self, state: State, handler): super().__init__(self) self.state = state self.square = ft.ElevatedButton( ・・・ ), on_click = handler ) ・・・
実はこの修正はかなり違和感が有ります。
Boardクラスのメソッドはこの様な感じです。
黄色の矢印の"self"はBoardクラスのインスタンスを示していますが
赤色の矢印の"self"はクリックハンドラとして渡してしまう為、
Squareクラスのインスタンスを意味します。
絶対に間違えるし、絶対に良くないとは思う。どうすれば・・・。
状態を覚えておくスコープの大きい何かを作り、ハンドラは
自身のクラス内に戻した方がはるかに分かりやすいのに。
ここまで修正したところで、実際の結果はこの辺りから
変わっていません・・・。
FletでReactチュートリアルを真似る3 - C#ATIA
この後は、チュートリアルではSquareクラスを関数化していますが、
関数化に出来るような気がしない為、クラスのまま進めます。