如何使用 MobX、mobx-react-lite 触发类似 setState 的状态?
How to trigger a state like setState with MobX, mobx-react-lite?
我想用 mobx 将状态转换为全局状态。我正在努力在 mobx 中创建一个全局状态。另外,我想提一下我正在使用 mobx-react-lite
库。
这里是codesanbox的link。如果你打开命令,你将能够看到它在使用 useState 之前是如何工作的。 https://codesandbox.io/s/mobx-react-lite-example-dfkm2y?file=/src/App.tsx
这是我的商店
import { observable, action } from "mobx";
export class ProductStore {
@observable categories: string[] = [];
@action
addCategory = (val: string) => {
this.categories.push(val);
};
@action
removeCategory = (val: string) => {
this.categories = this.categories.filter((f) => f !== val);
};
}
这是我的上下文
import { createContext, useContext } from "react";
import { ProductStore } from "./productStore";
type ProductContextValue = {
productStore: ProductStore;
};
const ProductContext = createContext<ProductContextValue>(
{} as ProductContextValue
);
const productStore = new ProductStore();
export const ProductProvider: React.FC<React.PropsWithChildren<{}>> = ({
children
}) => {
return (
<ProductContext.Provider value={{ productStore }}>
{children}
</ProductContext.Provider>
);
};
export const useStore = () => useContext(ProductContext);
我在组件中使用 addCategory 和 removeCategory 操作。当我进行调试时,我可以看到操作正常工作。
但是,我无法到达类别的更新。
这里是父组件
import "./styles.css";
import { ExampleComponent } from "./ExampleComponent";
import { useStore } from "./ProductContext";
import { useObserver } from "mobx-react-lite";
// import { useState } from "react";
export default function App() {
// const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
const { productStore } = useStore();
return useObserver(() => (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{/* old Version with useState */}
{/* {selectedCategories.map((m) => {
return <div>{m}</div>;
})} */}
{/* This section not working like a setState */}
{productStore.categories.map((m) => {
return <div>{m}</div>;
})}
<ExampleComponent
// selectedCategories={selectedCategories}
// setSelectedCategories={setSelectedCategories}
addCategory={productStore.addCategory}
removeCategory={productStore.removeCategory}
/>
</div>
));
}
我该如何解决这个问题?我在 mobx 部分看不到任何变化。
首先你需要在 store 构造函数中使用 makeObservable
以使其现在与装饰器一起工作,就像这样:
import { observable, action, makeObservable } from 'mobx';
export class ProductStore {
@observable categories: string[] = [];
constructor() {
makeObservable(this);
}
@action
addCategory = (val: string) => {
this.categories.push(val);
};
@action
removeCategory = (val: string) => {
this.categories = this.categories.filter((f) => f !== val);
};
}
其次,不要使用 useObserver
它已被弃用,使用 <Observer>
组件或用 observer
HOC 包装整个组件。
我想用 mobx 将状态转换为全局状态。我正在努力在 mobx 中创建一个全局状态。另外,我想提一下我正在使用 mobx-react-lite
库。
这里是codesanbox的link。如果你打开命令,你将能够看到它在使用 useState 之前是如何工作的。 https://codesandbox.io/s/mobx-react-lite-example-dfkm2y?file=/src/App.tsx
这是我的商店
import { observable, action } from "mobx";
export class ProductStore {
@observable categories: string[] = [];
@action
addCategory = (val: string) => {
this.categories.push(val);
};
@action
removeCategory = (val: string) => {
this.categories = this.categories.filter((f) => f !== val);
};
}
这是我的上下文
import { createContext, useContext } from "react";
import { ProductStore } from "./productStore";
type ProductContextValue = {
productStore: ProductStore;
};
const ProductContext = createContext<ProductContextValue>(
{} as ProductContextValue
);
const productStore = new ProductStore();
export const ProductProvider: React.FC<React.PropsWithChildren<{}>> = ({
children
}) => {
return (
<ProductContext.Provider value={{ productStore }}>
{children}
</ProductContext.Provider>
);
};
export const useStore = () => useContext(ProductContext);
我在组件中使用 addCategory 和 removeCategory 操作。当我进行调试时,我可以看到操作正常工作。
但是,我无法到达类别的更新。
这里是父组件
import "./styles.css";
import { ExampleComponent } from "./ExampleComponent";
import { useStore } from "./ProductContext";
import { useObserver } from "mobx-react-lite";
// import { useState } from "react";
export default function App() {
// const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
const { productStore } = useStore();
return useObserver(() => (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{/* old Version with useState */}
{/* {selectedCategories.map((m) => {
return <div>{m}</div>;
})} */}
{/* This section not working like a setState */}
{productStore.categories.map((m) => {
return <div>{m}</div>;
})}
<ExampleComponent
// selectedCategories={selectedCategories}
// setSelectedCategories={setSelectedCategories}
addCategory={productStore.addCategory}
removeCategory={productStore.removeCategory}
/>
</div>
));
}
我该如何解决这个问题?我在 mobx 部分看不到任何变化。
首先你需要在 store 构造函数中使用 makeObservable
以使其现在与装饰器一起工作,就像这样:
import { observable, action, makeObservable } from 'mobx';
export class ProductStore {
@observable categories: string[] = [];
constructor() {
makeObservable(this);
}
@action
addCategory = (val: string) => {
this.categories.push(val);
};
@action
removeCategory = (val: string) => {
this.categories = this.categories.filter((f) => f !== val);
};
}
其次,不要使用 useObserver
它已被弃用,使用 <Observer>
组件或用 observer
HOC 包装整个组件。