Open da1z opened 3 years ago
The short answer is there's no "one way" but I can share a pattern I've managed to scale out successfully.
Say you have some component props like:
export interface MyComponentProps extends RouteComponentProps<any> {
id: string | null
stateManager: MyStateManager
}
Then you have a component such as:
export class MyComponent extends React.Component<MyComponentProps, any> {
constructor(props: Readonly<MyComponentProps>) {
super(props)
}
render(): any: {
return (...)
}
}
Then you have some state management (this is just my pattern you may have some different use):
export interface MyStateManager {...}
import { injectable } from 'inversify'
@injectable()
export class SpecialStateManager implements MyStateManager {...}
So at this point you have a component and an interface and an injectable implementation. Now it is time to wire these together. One way to do this is to establish a container and configure dependencies.
I create a file container.ts
with:
import { Container, interfaces } from 'inversify'
...
// the container is created once, witin this module and used throughout the application
export const container = new Container()
...
container.bind<MyStateManager>('MyStateManager').to(SpecialStateManager).inSingletonScope()
Inside App.tsx
I would reference the pre-defined container like:
import { container } from '/path/to/container'
...
const App: React.FunctionComponent = () => {
const myStateManager = container.get<MyStateManager>('MyStateManager')
...
return (
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route exact path="/mypage/:id?" render={props => <MyComponent {...props} id={props.match.params.id} stateManager={myStateManager} />} />
Sorry I should have mentioned this. The benefit in this case is to allow swappable implementations of the state behind a react component, and swappable implementations of api clients, all driven by 2 REACT_APP_...
configurations settings
I think author asks about "how to run this" (typescript + cra+ inversify) without ejecting))) It's an old issue, now we can use "react-app-rewired" and "customize-cra" packages to achieve this goal. config.overrides.js must contain these lines:
module.exports = {
webpack: override(
/* for more info
* @see babel-plugin-parameter-decorator README
*/
addDecoratorsLegacy(),
...addBabelPlugins("babel-plugin-parameter-decorator"),
)
}
also, there will be minor problems in typescript, and finally, I can't find a solution for using auto declaration in constructor and using not string keys:
// works fine
private service: SomeService;
constructor(@inject('SomeService') service: SomeService) {
super(service);
this.service = service;
}
// doesn't work
constructor(@inject('SomeService') private service: SomeService) {
}
try to find more info for using inversify in components in google, but I don't recommend doing so, because react already has lazy loading, functional components, and hooks system.
Yes, my question is about using it without decorators or setting cra to accept them. As I understand there are no clear answer yet
any way to use inversify with create-react-app without ejecting? especially @inject in parameters