ReactでMobXを使用する方法を学習しようとしていますが、プロバイダーやコンテキストを使用する必要がある理由がわかりません。
例えば。 store.jsにストア(時間とともに変化する単純なタイマー)があります。
import { decorate, observable, action } from 'mobx';
import React from 'react';
class TheTimer {
currentTick = 0; // In seconds since start
tick = () => {
this.currentTick = Math.floor(performance.now() / 1000);
}
}
decorate(TheTimer, {
currentTick: observable,
tick: action
});
// Bare store
export const timerStore = new TheTimer();
// Store as React context
export const TimerStoreContext = React.createContext(timerStore);
// This makes the timer go
setInterval(timerStore.tick, 100);
これで、コンポーネントでベアストアを使用しても問題はありません。
import React from 'react';
import { configure } from 'mobx';
import { observer } from 'mobx-react';
import { timerStore } from './store';
configure({ enforceActions: 'observed' });
const App = observer(() => {
return (
<p>{timerStore.currentTick}</p>
);
});
export default App;
コンテキストの使用も機能します。
import React from 'react';
import { configure } from 'mobx';
import { observer } from 'mobx-react';
import { TimerStoreContext } from './store';
configure({ enforceActions: 'observed' });
const App = observer(() => {
const timerStore = React.useContext(TimerStoreContext);
return (
<p>{timerStore.currentTick}</p>
);
});
export default App;
(私はcreate-react-appとmobx、mobx-reactを使用しています、つまりReact 16.9.0とMobX 5.13.0とmobx-react 6.1.3)
ストアは一度作成され、それ以降は常に同じオブジェクトのままになります。
グローバル変数としてストアを直接使用するときに、誰でも(または古いmobx-react Providerベースのソリューション)コンテキストが使用されるのですか?
それはテスト容易性についてだけですか?
ReactではないJSコードもあることに注意してください。アプリケーションはWebsocketを介してサーバーと通信し、サーバーからの更新もアクションの呼び出しにつながります。そのコードはReactコンポーネントの外側にあるので、そのためにベアストアを使用する予定です。
コンテキストは主に、いくつかのデータが異なるネストレベルの多くのコンポーネントからアクセスできる必要がある場合に使用されます。コンポーネントの再利用が困難になるため、慎重に適用してください。
プロバイダーは、コンシューミングコンポーネントがコンテキストの変更をサブスクライブできるようにします。
Mobxでは、トップレベルのプロバイダーを使用して、プロバイダーでラップされたすべての子コンポーネントにすべてのストアインスタンスを渡します。
import { Provider } from "mobx-react";
<Provider {...Stores}>
<App/>
</Provider>
これで、inject Hocを使用して、子コンポーネント内のすべてのストアプロパティに小道具としてアクセスできます。
class App extends Component {
render() {
return <div>app</div>;
}
}
export default inject("app")(App);
Inject Hocを使用して複数のストアに注入し、複数のストアに格納されているプロパティにアクセスすることもできます
inject(stores => ({
abc: stores.abc,
bca: stores.bca
}))
したがって、mobxでも推奨されていない、コンポーネント内にストアを直接インポートする問題を解決します