C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

FletでReactチュートリアルを真似る6

こちらの続きです。
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クラスを関数化していますが、
関数化に出来るような気がしない為、クラスのまま進めます。