0

ここで説明されているのと非常によく似た、共有コンテキストを介して状態の更新を処理するUIプロジェクトに取り組んでいます

const {appState, dispatch} = useContext(AppContext);

一部のコンポーネントについては、xstate を使用してステート マシンをいじっていません。

const SomeComponent = () => {
  const {appState, dispatch} = useContext(AppContext);
  const [state,send,service] = useMachine(MyComponentStateMachine);
}

ここで、理想的には、ステートに入るときにステート マシンが特定のイベントをディスパッチするようにしたいと考えています。ステート マシンが AppContext を取得するための最良の方法は何ですか?

現時点では、コンポーネント自体でこのイベント ディスパッチを処理し、ステート マシンの状態を監視して、特定の状態になったときに必要に応じてイベントをディスパッチしています。

const SomeComponent = () => {
  const {appState, dispatch} = useContext(AppContext);
  const [state,send,service] = useMachine(MyComponentStateMachine);

  useEffect(() => service.subscribe(state => {
     if(state.value == "Some relevant state of MyComponentStateMachine")
       dispatch({type: SomeEvent, arg: 12345});  
    }).unsubscribe, [service]);
}

これはうまく機能しますが、設計が悪いと思います。このイベントは、コンポーネントからではなく、ステート マシンから直接ディスパッチする方がクリーンだと思います。

ステート マシンが AppContext を取得する良い方法はありますか?

ディスパッチを引数として取り、それを保持するステート マシンのファクトリ メソッドを単純に作成するのは賢明でしょうか?

4

1 に答える 1

0

そこでディスパッチ関数を呼び出すことは何も悪いことではないと思います。コンテキストを使用しているため、関数をパラメーターとして渡さない限り、マシン内でディスパッチを呼び出すことはできません。あなたはそれを試すことができますが、うまくいくかどうかはわかりません.

(アクションを使用して、イベントまたは状態の変化に対する副作用をトリガーできます)

その場合は、次のようになります。

<pre>
  //Component
  const SomeComponent = () => {
    const { appState, dispatch } = useContext(AppContext);
    const [ state, send ] = useMachine(MyComponentStateMachine);

    useEffect(() => {
      if(state.matches("stateName")) {
        const data = { type: SomeEvent, arg: 12345 };
        send("EVENT_NAME", { callback: dispatch, data })
      }
    }, [state]);
  }


  //Machine
  const MyComponentStateMachine = Machine({
    ...
    states: {
      stateName: {
        on: {
          EVENT_NAME: "secondState",
        },
      },
      secondState: {
        entry: ["actionName"]
      }
    },
    {
      actions: {
        actionName: (ctx, e) => {
          e.callback(e.data);
        },
      }
    }
  });
</pre>

*** また、状態を比較する方法も見てください。これは、状態値を読み取るためのよりクリーンな方法です。また、既に useMachine フックを使用している場合は、サービスにサブスクライブする必要はありません。状態が変化すると、フックはコンポーネントの再レンダリングをトリガーします。

于 2021-02-12T22:23:22.430 に答える