npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2024 – Pkg Stats / Ryan Hefner

reactject

v0.2.21

Published

React adapter of the TSyringe dependency injection container πŸ’‰

Downloads

63

Readme

GitHub npm npm

Reactject

Introduction

πŸŽ‰ Welcome to this framework that gives you full control over dependency management at runtime in React apps.

To keep it short, Reactject is the necessary piece to connect your React application with the dependency container in an elegant way.

Additionally the API adds new features and decorators to enhance the development experience.

Reactject is built on Microsoft's TypeScript efficient open source dependency container TSyringe.

Reasons to use Reactject

These are the reasons you didn't know why you should install Reactject in your React project.

React TSyringe adapter

Reactject exposes the TSyringe container and adds optimized hooks to resolve dependencies in functional components.

const MyComponent = () => {
  const gitHubService = useResolve(GitHubService);

  // TODO: use githubService to interact with the API

  return <div>This is my component</div>;
};

Full execution control

Reactject works as a TSyringe wrapper to decide when and where the modules registration begins.

The "module" concept is very similar to the Angular's one, but each module can choose between to use a child container or to register dependencies in the parent module container.

import {
  ReactjectModule,
  Reactject,
  module,
  DependencyContainer,
} from "reactject";
import GithubService from "./GithubService";

@module()
class AppModule extends ReactjectModule {
  register(container: DependencyContainer) {
    super(container);

    container.registerSingleton(GithubService);
  }
}

Reactject.start(AppModule);

Structured dependencies

Use our @module decorator to specify the submodules of a module. Modules will be registered recursively after Reactject.start(AppModule) execution.

@module({
  submodules: [PaymentModule, SharedModule],
})
class AppModule extends ReactjectModule {}

Reactject.start(AppModule);

All the dependencies of both PaymentModule and SharedModule will be registered when Reactject starts.

On-demand features

We are aware that there are still not too many functionalities nor is the direction of the project well defined.

But we can see this situation as an opportunity to listen to the community and develop, after an evaluation, the features that are most requested.

Support us and participate in the community to be part of the history of Reactject.

Installation

npm install reactject
yarn add reactject

Usage

Modules

In Reactject you register your dependencies organized by modules and when you start the root module (AppModule) the framework register all the submodules recursively.

Think modules are a pattern to group your dependencies and scope them with the container prop of the @module decorator. Dependencies in a module are by default registered in the global app container.

// GithubService.ts
import { injectable } from "reactject";
import axios from "axios";

@injectable()
class GitHubService {
  public readonly baseUrl = "https://api.github.com";

  public async getUser(username: string) {
    const response = await axios.get(`${this.baseUrl}/users/${username}`);

    return response.data;
  }
}

export default GitHubService;
// GithubModule.ts
import { ReactjectModule, Reactject, module } from "reactject";
import GithubService from "./GithubService";

@module({
  container: "child",
})
export class GithubModule extends ReactjectModule {
  register(container: DependencyContainer) {
    super(container);

    container.registerSingleton(GithubService);
  }
}
// AppModule.ts
import { ReactjectModule, Reactject, module } from "reactject";
import { GithubModule } from "./GithubModule";

@module({
  submodules: [GithubModule],
})
class AppModule extends ReactjectModule {}

Reactject.start(AppModule);

Registering

Register the classes or interfaces you are going to use as dependencies using the TSyringe decorators.

Check the TSyringe container documentation if you have any questions about its use.

Mark your class as @injectable and register it explicitly in a module.

// GithubService.ts
import { injectable } from "reactject";
import axios from "axios";

@injectable()
class GitHubService {
  public readonly baseUrl = "https://api.github.com";

  public async getUser(username: string) {
    const response = await axios.get(`${this.baseUrl}/users/${username}`);

    return response.data;
  }
}

export default GitHubService;
// GithubModule.ts
import { ReactjectModule, Reactject, module } from "reactject";
import GithubService from "./GithubService";

@module()
export class GithubModule extends ReactjectModule {
  register(container: DependencyContainer) {
    super(container);

    container.registerSingleton(GithubService);
  }
}

Resolving

Resolve the dependencies you have registered in the scopes where you need to use them.

Classes

To resolve dependencies within javascript classes we will not have to do anything special, since TSyringe is prepared to inject them through the constructor.

The following piece of code would allow us to inject dependencies into a class component.

import { inject } from "reactject";
import GitHubService from "../services/GitHubService";

class MyComponent {
  constructor(
    @inject(GitHubService) private readonly gitHubService: GitHubService
  ) {}

  private getUser() {
    return this.gitHubService.getUser("carlossalasamper");
  }

  private render() {
    return <div>This is my component</div>;
  }
}

export default MyComponent;

Hooks

Access the container dependencies transparently using the hooks we have prepared.

import { useResolve } from "reactject";
import GitHubService from "../services/GitHubService";

const MyComponent = () => {
  const gitHubService = useResolve(GitHubService);

  useEffect(() => {
    gitHubService.getUser("carlossalasamper");
  }, []);

  return <div>This is my component</div>;
};

export default MyComponent;

Third parties

⚠️ Creating classes that wrap the integrations would oversize the use of dependency injection in React and would also be very expensive to maintain.

To use our dependencies in the integration code of third parties that do not offer a class through which we can inject the objects that we need, we will access the container directly.

For example, to access the container from a Redux Toolkit AsyncThunk we would do it as follows:

import { container } from "reactject";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import GitHubService from "../services/GitHubService";

const getUser = createAsyncThunk(
  "github/getUser",
  async (username: string, thunkAPI) => {
    const gitHubService = container.resolve(GitHubService);
    return gitHubService.getUser(username);
  }
);

Examples

In the /examples folder you will find demo React applications that are using Reactject.

Support the project