为 React 函数组件创建一个新的 MobX store 实例
Create a new MobX store instance for a React function component
在 React 中使用 MobX 时,您可以在 class 组件实例上创建一个新的 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
实例?
我们可以使用 useState
挂钩,而不是使用 useObservable
挂钩,其函数 returns 一个新的 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>
在 React 中使用 MobX 时,您可以在 class 组件实例上创建一个新的 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
实例?
我们可以使用 useState
挂钩,而不是使用 useObservable
挂钩,其函数 returns 一个新的 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>