React Hooks (useState) and Mobx [No mobx-react-lite]

15,318

Solution 1

Thanks to @Tholle mentioning the Mobx version, now that the Mobx 6 is released this question is solved

Solution 2

mobx-react doesn't support hooks and if you wish to use hooks with mobx you need to make use of mobx-react-lite which is also mentioned in the github documentation

To do that you can make use of React.createContext instead of provider and useContext instead of inject

Index.tsx

import * as React from "react";
import { render } from "react-dom";
import MyComponent, { Store } from "./MyComponent";

import "./styles.css";
import MyStore from "./MyStore";

function App() {
  const [state, setState] = React.useState("");
  return (
    <Store.Provider value={MyStore}>
      <div className="App">
        <MyComponent id={"someID"} />
      </div>
    </Store.Provider>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

MyComponent.tsx

import * as React from "react";
import { Observer } from "mobx-react-lite";
import { MyStore } from "./MyStore";

interface IProps {
  myStore?: MyStore;
  id: string;
}

export const Store = React.createContext();
const MyComponent: React.FC<IProps> = props => {
  const [state, setState] = React.useState("");
  const store = React.useContext(Store);
  console.log(state, store);
  return (
    <div>
      <h1>{props.id}</h1>
    </div>
  );
};
export default MyComponent;

Working demo

Share:
15,318
Amir-Mousavi
Author by

Amir-Mousavi

Updated on June 09, 2022

Comments

  • Amir-Mousavi
    Amir-Mousavi almost 2 years

    in my react application (with typescript) I want to use React hooks (specifically useState) to manage the form state and meanwhile use it as an observable component for Mobx store but I get the error

    Hooks can only be called inside the body of a function component.

    so for instance in the following component

    import * as React from "react";
    import { inject, observer } from "mobx-react";
    import { MyStore } from "./MyStore";
    
    interface IProps {
      myStore?: MyStore;
      id: string;
    }
    
    const MyComponent: React.FC<IProps> = props => {
      const [state, setState] = React.useState("");
      return (
        <div>
          <h1>{props.id}</h1>
        </div>
      );
    };
    export default inject("myStore")(observer(MyComponent));
    

    I saw a solution but that was using React.createContext for exporting the store class. is not where the old approach for Mobx and Hooks?

    here is the sanbox for the example