MOBX REACT“ AUTORUN”在每次更改中呼叫更多次

发布于 2025-02-10 09:53:35 字数 1460 浏览 1 评论 0原文

我已经设置了一个具有单个数字值的简单应用程序存储,我在每次按钮时都会增加该数字值。我的UI很简单:一个单个应用< div>包含一个mychild组件,该组件呈现增量按钮旁边的数字。

应用程序的autorun似乎行为正确,但是每次我增加值时,mychild's autorun autorun fir 。如果我单击该按钮,它将发射两次。我再次单击,它发射了3次,依此类推。我希望每次增量,autorun会发射一次。我在这里想念什么?

代码可在

import "./styles.css";

import * as React from "react";
import { observer } from "mobx-react-lite";
import { action, autorun, makeAutoObservable } from "mobx";

class AppStore {
  v;
  constructor() {
    this.v = 0;
    makeAutoObservable(this);
  }
}
const appStore = new AppStore();

const MyChild = observer(() => {
  console.log("MyChild render", appStore.v);

  autorun(() => { // <------------------------ this gets fired extra times
    console.log("mychild autorun " + appStore.v);
  });

  return (
    <div style={{ backgroundColor: "lightBlue" }}>
      mychild {appStore.v}
      {": "}
      <button
        onClick={action(() => {
          appStore.v += 1;
        })}
      >
        INC
      </button>
    </div>
  );
});

export default observer(function App() {
  console.log("app render");

  autorun(() => {
    console.log("app autorun " + appStore.v);
  });

  return (
    <>
      <div style={{ backgroundColor: "gray", padding: "10px" }}>
        main
        <MyChild />
      </div>
    </>
  );
})

I've setup a simple app store with a single numeric value, which I increment on every button click. My UI is simple: a single app <div> which contains a MyChild component that renders the number next to an increment button.

The app's autorun seems to behave correctly BUT every time I increment the value, MyChild's autorun fire extra times i.e. on page load it fires once. If I click the button, it fires twice. I click again, it fires 3 times, and so on. I expect that on every increment, autorun would fire once. What am I missing here?

Code is available on CodeSandbox
Here it is here as well:

import "./styles.css";

import * as React from "react";
import { observer } from "mobx-react-lite";
import { action, autorun, makeAutoObservable } from "mobx";

class AppStore {
  v;
  constructor() {
    this.v = 0;
    makeAutoObservable(this);
  }
}
const appStore = new AppStore();

const MyChild = observer(() => {
  console.log("MyChild render", appStore.v);

  autorun(() => { // <------------------------ this gets fired extra times
    console.log("mychild autorun " + appStore.v);
  });

  return (
    <div style={{ backgroundColor: "lightBlue" }}>
      mychild {appStore.v}
      {": "}
      <button
        onClick={action(() => {
          appStore.v += 1;
        })}
      >
        INC
      </button>
    </div>
  );
});

export default observer(function App() {
  console.log("app render");

  autorun(() => {
    console.log("app autorun " + appStore.v);
  });

  return (
    <>
      <div style={{ backgroundColor: "gray", padding: "10px" }}>
        main
        <MyChild />
      </div>
    </>
  );
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨落□心尘 2025-02-17 09:53:35

我找到了原因(我是MOBX反应的新手,猜想我应该弄清楚)
根据 this提示,我需要设置autorunoorun在第一次渲染上发生的使用。我将所有的自动运输更改为:

React.useEffect(() => {
    return autorun(...);
}, []);

现在每次渲染一次都会被解雇。

I have found the reason (I'm new to Mobx-React, guess I should have figured it out)
According to this tip, I need to setup autorun inside a useEffect that happens on first render. I changed all my autoruns to:

React.useEffect(() => {
    return autorun(...);
}, []);

and now they get fired once every render.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文