天落枫 2021-07-18 17:01 采纳率: 100%
浏览 1261
已采纳

react hook组件使用mobx,mobx状态更新但react页面不刷新!

我想使用函数组件来重构类组件,在函数组件中使用了hook,同时发现改变mobx状态,页面不刷新,只有改变hook的state页面才更新

store.js

import { observable, action } from "mobx";

class CountStore {
  @observable a = 1;
  @observable b = 2;

  @action
  add = () => {
    this.a++;
  };
  @action
  add2 = () => {
    this.b++;
  };
}

const countStore = new CountStore();
export default countStore;

App.js

import { observer } from "mobx-react";

import React, { useEffect, useState } from "react";

const App = (props) => {
  const [x, setX] = useState(0);

  useEffect(() => {
    console.log(props);
  });

  return (
    <div className="App">
      <div>x:{x}</div>
      <div>{props.store.a}</div>
      <div>{props.store.b}</div>
      <button onClick={setX.bind(null, x + 1)}>set x</button>
      <button onClick={props.store.add}>add按钮1</button>
      <button onClick={props.store.add2}>add2按钮2</button>
      <br />
    </div>
  );
};

export default observer((props) => {
  return <App store={props.store} />;
});

index.js

// 省略一些
ReactDOM.render(<App store={countStore} />, rootElement);

如果使用:export default observer(App);导出,则会报错:Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

实在是不知道怎么改了,请大 佬帮 忙看 看,十分 感 谢

  • 写回答

2条回答 默认 最新

  • 天落枫 2021-07-19 23:19
    关注

    问题出在当前版本的mobx-react和react不支持使用hook,升级到mobx和mobx-react都为6.1.0版本后问题解决,升级后可以选择两种方式来生成一个store:
    方法一:使用makeObservable,但是需要标注一下哪些属性进行转换。
    方法二:使用makeAutoObservable,自动转换所有属性,无需装饰器标。
    用法注详情参考:mobx快速入门

    修改完后代码为:
    index.js

    import { Provider } from "mobx-react";
    import { StrictMode } from "react";
    import ReactDOM from "react-dom";
    
    import App from "./App";
    
    import countStore from "./countStore";
    const rootElement = document.getElementById("root");
    ReactDOM.render(
      <StrictMode>
        <Provider countStore={countStore}>
          <App />
        </Provider>
      </StrictMode>,
      rootElement
    );
    

    App.js

    import { observer, MobXProviderContext } from "mobx-react";
    
    import React, { useEffect, useState } from "react";
    
    const App = observer((props) => {
      const [x, setX] = useState(0);
      const { countStore } = React.useContext(MobXProviderContext);
    
      useEffect(() => {
        console.log("1", props);
      });
    
      return (
        <div className="App">
          <div>x:{x}</div>
          <div>{countStore.a}</div>
          <div>{countStore.b}</div>
          <button onClick={setX.bind(null, x + 1)}>set x</button>
          <button onClick={countStore.add}>add按钮1</button>
          <button onClick={countStore.add2}>add2按钮2</button>
          <br />
        </div>
      );
    });
    
    export default App;
    

    countStore.js

    import { makeAutoObservable } from "mobx";
    
    class CountStore {
      constructor() {
        makeAutoObservable(this);
      }
      a = 1;
      b = 2;
    
      add = () => {
        this.a++;
      };
    
      add2 = () => {
        this.b++;
      };
    }
    
    const countStore = new CountStore();
    export default countStore;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已采纳回答 7月19日
  • 创建了问题 7月18日

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line