2

I'm pretty new to React, and I would essentially have a service (one single instance) that I could somehow inject and use in multiple React components.

So far, the options I've come across by googling were:

  • Using React's context, but it's not recommended, because it is an undocumented API.
  • Passing the object along in the props, from component to component, but it feels a bit inelegant and tedious
  • Using an IoC container, such as inversifyJS, who looks great, only it relies on typescript, and I don't wish to write my React app in typescript.

Now, Inversify can apparently be used in vanilla JS, with inversify-vanillajs-helpers, but when I tried using it in React to resolve a component (my App component), it kept throwing an exception stating

"Missing required @injectable annotation in: ReactComponent"

So, I'm trying to figure out a way to get an instance of my service (the same instance shared across the few components that use it), either by making inversify work with React but without typescript, or a new approach I haven't explored yet.

Any ideas ?

Fabio Salvalai
  • 2,479
  • 17
  • 30
  • You can make high order service components and then wrap your React components with it. – Shota Feb 04 '17 at 14:23

1 Answers1

0

There are a few things that you can do if you don't like TypeScript:

First, you are going to need the inversify.decorate method.

Second, this method is probably going to be too verbose for you. We created a helper called inversify-vanillajs-helpers for that reason.

And third, React doesn't play nicely with constructor injection so we created a helper to facilitate lazy property injection called inversify-inject-decorators.

Those three tools should lead yo to the desired result :)

Remo H. Jansen
  • 23,172
  • 11
  • 70
  • 93
  • unfortunately, it seems inversify-inject-decorators requires TypeScript. Is there a vanillaJS version of the package ? couldn't find any. Or perhaps a way to use decorate in order to annotate properties for property injection ? – Fabio Salvalai Feb 04 '17 at 17:37
  • Status update: I tried annotating my React component with ``inversify-vanillajs-helpers``, and as it still wasn't working, I tried to remove all injected dependencies (and adapted the call to ``annotate`` to reflect that.) Then, I tried to resolve the controller (with no dependency being injected) and I still have the same message: Missing required @injectable annotation in: ReactComponent. (note that if I don't call annotate, I have a similar message, but it mentions ``App``, not ``ReactComponent``.) – Fabio Salvalai Feb 04 '17 at 18:30
  • if I use the vanillajs helpers package to annotate ReactComponent as well, then I get a new error message: _The number of constructor arguments in the derived class App must be >= than the number of constructor arguments of its base class._ – Fabio Salvalai Feb 04 '17 at 18:50
  • Hi sorry for the late reply... you are correct, at the moment this is not supported. I recommend you to close this SO question we will deal with this on GitHub as it is a feature request (not a question). You can follow the process of implementation at https://github.com/inversify/InversifyJS/issues/489 – Remo H. Jansen Feb 06 '17 at 09:19