@myskypesla

Как правильно работать с mobx?

Есть 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();


Есть App.js:
import React, { Component } from 'react';
import Form from './components/Form';

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

export default App;


Есть 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'));


Есть Form.js
import React, { Component } from 'react';

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

export default Form;


Вопрос 1: как импортировать mobx -> store глобально, чтобы в каждом компоненте, без лишних вызовов, store был доступен?
Вопрос 2: как вызвать метод store.js -> getUsers() из компонента Form.js?
  • Вопрос задан
  • 1797 просмотров
Решения вопроса 1
@supfiger
Ответ 1:

  1. Импортируешь Provider в файл index.js, чтобы не пробрасывать props через каждый дочерний компонент:
    import { Provider } from "mobx-react";
  2. В файле index.js оборачиваешь компонент рендеринга в Provider:
    ReactDOM.render(<Provider store={store}>
        <App />
      </Provider>, document.getElementById('root'));
  3. Импортируешь inject в нужный компонент, где нужно использовать тебе store:
    import { inject } from "mobx-react";
  4. Если классовый компонент, можешь повесить @inject("store") перед объявлением класса, где значение в скобках — название твоего пропса, который ты передаешь в Provider в 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. Если компонент функциональный, то можно сделать так:
    import React from "react";
    import { inject } from "mobx-react";
    
    const App = () => {
      return <div className="App">Hello World!</div>;
    };
    
    export default inject("store")(App);


Ответ 2:
  1. Теперь доступ к store есть из любого компонента, который находится в дереве Provider и на котором повешен @inject("store").
    Чтобы вызвать метод из стора, следуй примеру ниже. Допустим, вызовем метод по нажатию кнопки:
    <button onClick={() => this.props.store.getUsers()}></button>
    И, насколько я понимаю, нужно обернуть вызываемую функцию в стрелочную функцию, то есть: () =>, если нужный метод находится за пределами текущего файла. В твоем случае — да.

    Можешь еще сделать деструктуризацию, и обращаться сразу к нужному методу:
    const { getUsers } = this.props.store;
      // какой-то код
    
      return <button onClick={() => getUsers()}></button>;
    };



Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы