web-dev-qa-db-fra.com

Pourquoi dois-je utiliser Context ou un fournisseur avec MobX?

J'essaie d'apprendre à utiliser MobX avec React, et je ne comprends pas pourquoi l'utilisation d'un fournisseur ou d'un contexte est nécessaire, si l'objet qui contient l'état ne change jamais, seulement son contenu.

Par exemple. J'ai un magasin (une simple minuterie qui change avec le temps) dans 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);

Maintenant, il n'y a plus de problème à utiliser le magasin nu dans un composant:

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;

L'utilisation du contexte fonctionne également:

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;

(J'utilise create-react-app plus mobx, mobx-react, c'est-à-dire React 16.9.0 avec MobX 5.13.0 et mobx-react 6.1.3))

Notez que le magasin est créé une fois et à partir de là, il reste toujours le même objet.

Pourquoi le contexte est-il utilisé par tout le monde (ou par les anciennes solutions basées sur Mobx-react Provider) lors de l'utilisation directe du magasin comme variable globale?

S'agit-il uniquement de testabilité?

Notez que j'ai également du code JS qui n'est pas React, l'application communique via Websockets avec le serveur et les mises à jour à partir du serveur entraîneront également l'appel d'actions; Je prévois d'utiliser le magasin nu pour cela car ce code vit en dehors des composants React.

6
RemcoGerlich

Le contexte est principalement utilisé lorsque certaines données doivent être accessibles par de nombreux composants à différents niveaux d'imbrication. Appliquez-le avec parcimonie car cela rend la réutilisation des composants plus difficile.

Le fournisseur permet aux composants consommateurs de s'abonner aux changements de contexte.

Dans Mobx, nous utilisons des fournisseurs au niveau supérieur pour transmettre toutes les instances de magasin à tous les composants enfants qui sont encapsulés avec le fournisseur, par exemple

import { Provider } from "mobx-react";


<Provider {...Stores}>
   <App/>
 </Provider>

Maintenant, nous pouvons accéder à toutes les propriétés du magasin à l'intérieur du composant enfant en tant qu'accessoires en utilisant l'injection Hoc, par exemple

class App extends Component {
  render() {
    return <div>app</div>;
  }
}

export default inject("app")(App);

Vous pouvez également injecter plusieurs magasins à l'aide d'Inject Hoc pour accéder aux propriétés stockées dans plusieurs magasins

inject(stores => ({
 abc: stores.abc,
 bca: stores.bca
}))

Cela résoudra donc le problème de l'importation du magasin directement à l'intérieur du composant, ce qui n'est pas non plus recommandé par mobx

0
Vipin Yadav