Search code examples
reactjsreact-contextunstated

Calling unstated function using componentDidMount or from another file


I am trying to create a context to store all the info needed for my app, the code below works but I do have limitations, this is Api.js where I want to put all the logic and API requests/responses.

import { Provider, Subscribe, Container } from "unstated";
import fire from "./config/Fire";

class APIContainer extends Container {
  constructor(props = {}) {
    super();
    this.state = {
      loggedIn: false,
      loading: null,
    };
  }
  async auth() {
    fire.auth().onAuthStateChanged((user) => {
      if (user) {
        this.setState({ loggedIn: true, loading: false });
      }
      else {
        this.setState({ loggedIn: false, loading: false });
      }
    });
  }
}

const Api = {
  Instance: new APIContainer(),
  Provider,
  Subscribe
};

export default Api;

This App.js <Routes /> is a basic react router with few paths

 <Api.Provider inject={[Api.Instance]}>
    <Routes />
 </Api.Provider>

On components I can use the context but only in render method like so :

<Api.Subscribe to={[Api.Instance]}>
{api => (
   <p>String(api.state.loggedIn)</p>
   <button onClick={() => api.auth()}>run</button>
  )}
 </Api.Subscribe>

Now my goal is to either implement a componentDidMount in the APIContainer or access the function on any component, I tried with props didn't worked!

componentDidMount = () => {
 this.props.api.auth();
}

Please advise


Solution

  • As your code, the api.auth() just valid inside Subscribe, it is invalid at componentDidMount.

    If you want to auto-auth at componentDidMount, you should make a child component, and pass auth() to it.

    I made an example for you. You can see that you want on the console.

    a unstated example