Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injection fails inside the constructor of React components #1

Open
ghost opened this issue Jan 9, 2019 · 2 comments
Open

Injection fails inside the constructor of React components #1

ghost opened this issue Jan 9, 2019 · 2 comments
Labels
question Further information is requested

Comments

@ghost
Copy link

ghost commented Jan 9, 2019

I wish I could give this project more stars, because it has saved me a lot of time and made my code much cleaner. Thanks for the awesome library!

There's one issue I'm having, though. I'm trying to use a dependency inside the constructor of a React component, and somehow the library always complains with the following error:

Error: Provider is not found.
  Please define Provider and set Loader.contextType = InjectorContext e.g.
  @provider([MyService, MyService])
  class App extends React.Component { /*...*/ }
  class Loader extends React.Component {
    static contextType = InjectorContext;
  }

I've set up everything in accordance with the documentation (I think).

@provider([Session, toClass(Session)])
class App extends React.Component {
  render() {
    if (this.state.loading) {
      return <Loader />
    }
    // ...
  }
}

class Loader extends React.Component {

  @inject session: Session
  
  constructor(props) {
    super(props)
    this.session.doSomethingUseful()  
  }
  
  render() {
    // ...
  }

  static contextType = InjectContext

}

Is there something I'm missing, or is this use case currently not supported by the library? Everything works fine if I defer accessing the dependency in <Loader /> to componentDidMount, so I'm guessing this is either a bug or a limitation.

@gnaeus
Copy link
Owner

gnaeus commented Jan 15, 2019

Thanks! I should update the docs.

This library use React.Context under the hood. And if you want to use dependency inside constructor — you should pass the context argument to super(). See explainaition from Dan Abramov.

TL;DR
If you don't pass props or context to super() React assign it to this.props and this.context immediately after your component constructor call. But if you want to use it inside constructor — you should call super(props, context).

@provider(Session)
 class App extends React.Component {
    render() {
      return <Loader />;
    }
}

class Loader extends React.Component {
  @inject session: Session;

  constructor(props, context) {
    super(props, context);
    this.session.doSomethingUseful();
  }
}

Also, if you use @inject decorator, you don't need to manually specify static contextType = InjectorContext. The decorator is already doing this for you.

@ghost
Copy link
Author

ghost commented Jan 15, 2019 via email

@gnaeus gnaeus added the question Further information is requested label Jan 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant