M
M
myskypesla2018-10-05 15:00:56
React
myskypesla, 2018-10-05 15:00:56

How to work with mobx?

There is store.js:

import { observable, action } from 'mobx';
import axios from 'axios';

class Store {
  @observable users = null;

  @action
  getUsers() {
    axios.get('https://jsonplaceholder.typicode.com')
      .then((response) => {
        this.categories = response.data;
      })
      .catch(error => console.error(error));
  }
}

export default new Store();

There is App.js:
import React, { Component } from 'react';
import Form from './components/Form';

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

export default App;

There is index.js
import React from 'react';
import ReactDOM from 'react-dom';
import store from './store';
import App from './App';

ReactDOM.render(<App store={store} />, document.getElementById('root'));

There is Form.js
import React, { Component } from 'react';

class Form extends Component {
  render() {
    return (
      <form className="form">
        <select>
          <option></option>
        </select>
      </form>
    );
  }
}

export default Form;

Question 1: how to import mobx -> store globally so that in each component, without unnecessary calls, the store is available?
Question 2: how to call store.js -> getUsers() method from Form.js component?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Danil Zinchenko, 2020-06-04
@myskypesla

Answer 1:

  1. Importing Provider in index.js file so you don't have to pass props through every child component:
    import { Provider } from "mobx-react";
  2. In the index.js file, you wrap the render component in a Provider :
    ReactDOM.render(<Provider store={store}>
        <App />
      </Provider>, document.getElementById('root'));
  3. You import inject into the required component, where you need to use store :
    import { inject } from "mobx-react";
  4. If a class component, you can hang @inject("store") before the class declaration, where the value in brackets is the name of your prop that you pass to the Provider in index.js:
    import React, { Component } from 'react';
    import { inject } from "mobx-react";
    
    @inject("store")
    class Form extends Component {
      render() {
        return (
          <form className="form">
            <select>
              <option></option>
            </select>
          </form>
        );
      }
    }
    
    export default Form;
  5. If the component is functional , then you can do this:
    import React from "react";
    import { inject } from "mobx-react";
    
    const App = () => {
      return <div className="App">Hello World!</div>;
    };
    
    export default inject("store")(App);

Answer 2:
  1. Now access to the store is from any component that is in the Provider tree and on which @inject("store") is hung to it .
    To call a method from a store, follow the example below. Let's call the method on button click:
    <button onClick={() => this.props.store.getUsers()}></button>
    And, as far as I understand, you need to wrap the called function in an arrow function, that is: () =>if the desired method is outside the current file. In your case, yes.
    You can also do destructuring, and immediately access the desired method:
    const { getUsers } = this.props.store;
      // какой-то код
    
      return <button onClick={() => getUsers()}></button>;
    };

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question