如何解决React + Mobx 如何改变不同组件的值并随处显示变化?
https://codesandbox.io/s/react-mobx-change-value-in-several-components-f2tuu
如何改变不同地方的变量? 变量是一个,但它在不同的组件中分别发生变化,并且这些在一个组件中的变化不会反映在另一个组件中。
App.js
import AppStore from "./AppStore";
import { observer } from "mobx-react";
import SomeComponent from "./SomeComponent";
const store = AppStore();
const App = observer(() => {
return (
<div className="App">
<div>
<i>This is text in App:</i> {store.text}
</div>
<div>
<button
onClick={() => {
store.changeText("This is text from App");
}}
>
Change text from App
</button>
</div>
<SomeComponent />
</div>
);
});
export default App;
SomeComponent.js
import React from "react";
import AppStore from "./AppStore";
import { observer } from "mobx-react";
const store = AppStore();
const SomeComponent = observer((props) => {
return (
<div>
<div>
<i>This is text in component:</i> {store.text}
</div>
<div>
<button
onClick={() => store.changeText("This is text from component")}
>
Change text from component
</button>
</div>
</div>
);
});
export default SomeComponent;
AppStore.js
import { action,makeObservable,observable } from "mobx";
export default function AppStore() {
return makeObservable(
{
text: "Initial text",changeText(data) {
this.text = data + ": " + new Date().toLocaleTimeString();
}
},{
text: observable,changeText: action
}
);
}
解决方法
在您的 App
组件中,您通过此代码 store
创建了一个对象变量 const store = AppStore();
。然后你使用它,显示它,改变它等等。稍后在您的 SomeComponent
组件中,您通过 store
创建一个新变量 const store = AppStore();
。即使变量名称相同并且使用对象,这些也是 2 个不同的变量。因此,为什么更新一个不会更新另一个。在 DOM 内部,它们是不同的对象。要修复它而不是在 SomeComponent
内创建新对象,只需从父组件传递 store
。在 App
中,渲染 SomeComponent
时将 store
变量传递给它
<SomeComponent store={store} />
在你的 SomeComponent
中从 props 中取出并使用它
import React from "react";
import { observer } from "mobx-react";
const SomeComponent = observer(({ store }) => {
return (
<div>
<div>
<i>This is text in component:</i> {store.text}
</div>
<div>
<button onClick={() => store.changeText("This is text from component")}>
Change text from component
</button>
</div>
</div>
);
});
export default SomeComponent;
这样两个组件都可以更改相同的变量数据。
编辑。我分叉了你的项目并编辑了代码以匹配我在这里发布的内容,这样你就有了一个活生生的例子来分析。 https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-4c7uk?file=/src/SomeComponent.js
,我找到了 React Context 的解决方案。 很抱歉没有立即添加到这里。 不幸的是,很难理解 Mobx 文档。
首先,我们需要创建上下文并创建提供者:
import { useLocalStore } from "mobx-react";
import React from "react";
import AppStore from "./AppStore";
export const AppStoreContext = React.createContext();
export const AppStoreProvider = ({ children }) => {
const store = useLocalStore(AppStore);
return (
<AppStoreContext.Provider value={store}>
{children}
</AppStoreContext.Provider>
);
};
export const UseAppStore = () => React.useContext(AppStoreContext);
export default AppStoreProvider;
AppStore.js 在哪里:
import { action,makeObservable,observable } from "mobx";
export default function AppStore() {
return makeObservable(
{
text: "Initial text",changeText(data) {
this.text = data + ": " + new Date().toLocaleTimeString();
}
},{
text: observable,changeText: action
}
);
}
然后,我们需要在 index.js 中使用:
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import AppStoreProvider from "./AppStoreProvider";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<AppStoreProvider>
<App />
</AppStoreProvider>,rootElement
);
然后我们可以使用上下文:
import "./styles.css";
import React from "react";
import { UseAppStore } from "./AppStoreProvider";
import { observer } from "mobx-react";
import SomeComponent from "./SomeComponent";
const App = observer(() => {
const store = UseAppStore();
return (
<div className="App">
<div>
<i>This is text in App:</i> {store?.text}
</div>
<div>
<button
onClick={() => {
store.changeText("This is text from App");
}}
>
Change text from App
</button>
</div>
<SomeComponent />
</div>
);
});
export default App;
或者像这样:
import { useContext } from "react";
import { AppStoreContext } from "./AppStoreProvider";
import { observer } from "mobx-react";
const SomeComponent = observer((props) => {
const store = useContext(AppStoreContext);
return (
<div>
<div>
<i>This is text in component:</i> {store.text}
</div>
<div>
<button onClick={() => store.changeText("This is text from component")}>
Change text from component
</button>
</div>
</div>
);
});
export default SomeComponent;
希望对某人有用
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。