为React函数组件创建一个新的MobX存储实例

时间:2019-02-21 00:23:54

标签: javascript reactjs mobx mobx-react

将MobX与React结合使用时,您可以在类组件实例上创建一个新的Store实例,如下所示:

const { extendObservable } = mobx;
const { Observer } = mobxReact;

class Store {
  constructor() {
    console.log("Created a store");
    extendObservable(this, {
      count: 0
    });
  }
}

class App extends React.Component {
  store = new Store();

  render() {
    const { store } = this;

    return (
      <Observer>
        {() => <button onClick={() => ++store.count}>{store.count}</button>}
      </Observer>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mobx@5.9.0/lib/mobx.umd.min.js"></script>
<script src="https://unpkg.com/mobx-react-lite@1.0.1/dist/index.min.js"></script>

<div id="root"></div>

将其转换为功能组件时,它仍然可以工作,但是每个渲染都会创建一个新的Store实例,该实例将不被使用。这不仅浪费,而且如果构造函数包含其他逻辑,可能会具有不良行为。

const { extendObservable } = mobx;
const { observer, useObservable } = mobxReact;

class Store {
  constructor() {
    console.log("Created a store");
    extendObservable(this, {
      count: 0
    });
  }
}

const App = observer(() => {
  const store = useObservable(new Store());
  
  return <button onClick={() => ++store.count}>{store.count}</button>
});

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mobx@5.9.0/lib/mobx.umd.min.js"></script>
<script src="https://unpkg.com/mobx-react-lite@1.0.1/dist/index.min.js"></script>

<div id="root"></div>

有没有一种方法可以仅在功能组件的第一个渲染上创建一个单独的Store实例?

1 个答案:

答案 0 :(得分:0)

我们可以使用useObservable钩子而不是使用useState钩子,该函数可以返回一个新的Store作为参数。此函数只会在第一次渲染时被调用一次,因此只能创建一个Store实例。

const { useState } = React;
const { extendObservable } = mobx;
const { observer, useObservable } = mobxReact;

class Store {
  constructor() {
    console.log("Created a store");
    extendObservable(this, {
      count: 0
    });
  }
}

const App = observer(() => {
  const [store] = useState(() => new Store());
  
  return <button onClick={() => ++store.count}>{store.count}</button>
});

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mobx@5.9.0/lib/mobx.umd.min.js"></script>
<script src="https://unpkg.com/mobx-react-lite@1.0.1/dist/index.min.js"></script>

<div id="root"></div>