motivation
React is a JavaScript library for building UIs, but when developing applications based on React, there is often a lot of build configuration and selection of other libraries (picking and learning a React state library, router library, etc.). We also need to consider how abstract and structured our business logic should be. Every React developer is practicing what they know about React builds, but it doesn’t allow us to quickly focus on the business logic itself. As the application business grows, we urgently need a framework that is easy to understand and maintain.
For structuring the business logic of your application, separation of concerns is a good idea. It requires clear boundaries of responsibility to avoid low maintainability when UI logic and business logic mix. When we build applications, we always focus on business logic. It is one of the core business values of an application. We want it to be easy to maintain and test. Redux remains the most popular state library in React. It fully conforms to the principle of React immutable. Redux is just a container of states, and we often don’t know how to really manage those states. We needed an extensible, loosely coupled, and easily maintainable React application framework.
React is a great UI library, but even with hooks on React, it’s not enough to solve the problems we have in developing large applications. We still don’t have module dependency injection, we don’t have a good AOP practice model, we don’t have a good chance of minimizing module system abstraction, we don’t have a good practice of DDD, and so on. These problems are not React, we need to think about and solve.
Of course, I’m not talking about whether React needs any of these features, it’s good enough. The real question here is: Do we need a React framework?
To address these architectural issues, Reactant was born — a React framework.
Introduction of Reactant
Reactant efficiently builds scalable, maintainable React applications. Reactant is based on TypeScript, but it supports both TypeScript and JavaScript (TypeScript is recommended for a better development experience). Reactant provides dependency injection, a modular model, immutable state management, module dynamics, and more. It is plug-in and highly testable. Not only does it quickly build React applications (Web and Native Mobile), it also brings some new React development experiences. Reactant also keeps the right amount of flexibility. With Reactant, you can still embrace OOP, FP, FRP programming paradigms, and you can still embrace the React ecosystem.
Reactant is inspired by many of Angular’s best features, such as Reactant’s dependency injection API, which is similar to Angular. Reactant isn’t a clone of Angular programming ideas on the React framework, however. Reactant provides fewer and cleaner apis that can be used in a variety of application development scenarios.
It is a complete architecture for React.
What problem was solved
Reactant is an incremental framework. In the process of application development from simple to complex, it can provide suitable features at each stage, and the system architecture design based on it can also carry out various gradual smooth upgrade and evolution.
Better IMmutable state management
React is the preferred immutable state type for management, and Redux clearly fits into it. But in fact, simple, mutated updates like MobX are more and more in line with the current trend. Therefore, Reactant provides a new immutable state management model based on Redux and Immer, which incorporates similar API elements from MobX and, more importantly, maintains state immutability.
@injectable(a)class TodoList {
@state
list: Todo[] = [];
@action
addTodo(text: string) {
this.list.push({ text, completed: false}); }}Copy the code
modular
Although it seems that the entire React community is increasingly embracing functional programming after the introduction of Hooks, functional programming is not necessarily the best solution in a complex enterprise business. Of course, Hooks do provide a great solution for decoupling rendering logic if you only build the UI. But in the business logic realm, we have better options, especially for collaborative development in an enterprise application, and the fact that class-based module design often leads to parallel development and easy maintenance and testing. Classes are not harmful, bad module design is.
Therefore, Reactant advocates the use of class for Module implementation. More importantly, Reactant defines the Service Module, View Module, and Plugin Module to make their responsibilities and boundaries clearer. Any Module can be a Service Module, it is flexible, many different application architecture can be based on it; The View Module must define the View component bound to the current Module. It is the rendering entry for the View Module. The Module state it depends on is injected visually through useConnector. The Plugin Module is a complete Redux middleware and Context wrapper that provides a model for designing plug-ins that makes the simplicity of the plug-in API possible.
In addition, Reactant provides a full dependency injection API. DI, implemented based on TypeScript decorator metadata, makes it particularly easy to use.
@injectable(a)class AppView extends ViewModule {
constructor(public counter: Counter) {
super(a); }component() {
const count = useConnector(() = > this.counter.count);
return (
<button
type="button"
onClick={()= > this.counter.increase()}>
{count}
</button>); }}Copy the code
Simple and lightweight
Reactant has no more than 30 apis and even fewer than 15 core apis. Without too much familiarity or adaptation, you can quickly get used to Reactant and use it to develop any complex React application.
At runtime, the gzip compression of Reactant’s core code is less than 50KB. Not only does Reactant support code splitting, it also supports dynamic module injection, which is great for many large applications running at a minimum.
Embrace React Ecology
Reactant is open, and Reactant based on React and Redux abstracts some of the models. While these apis bring convenience to developers, they also support the React and Redux ecosystems. There are many excellent third-party libraries that can be used directly on Reactant or repackaged, which opens up a lot of possibilities for Reactant applications.
Better development experience
Reactant provides more compact routing modules (reactant-router) and persistence modules (reactant-storage). If necessary, you can develop any better module API you need based on the Reactant plug-in module.
During debugging, devOptions supports autoFreeze and reduxDevTools. When autoFreeze is enabled, any operation that does not change state in the @Action decorated function will report an error; When reduxDevTools is enabled, Reactant will activate DevTools support for Redux.
Reactant is still very new, and more features to improve the development experience are in the works.
performance
In benchmark performance tests of Reactant and MobX+React, Reactant had an advantage in startup time and derivative calculations, while MobX+React had an advantage in value updates. Overall, there was no significant performance difference between the two. Because Reactant is based on Immer, Reactant also provides a performance optimization solution for the rare extreme performance bottlenecks.
Reactant is committed to building a productive React framework while maintaining good performance.
conclusion
Reactant was designed to help React developers efficiently build and develop maintainable, testable applications. The goal of Reactant is to minimize the lifetime cost of the system and maximize developer productivity.
As a new framework, Reactant has only been in development for a few months, and there is still a lot of work to be done, including building the toolset, developing the toolset, SSR, and React Native CLI.
If you’re already familiar with React, all you need to do is quickly read the Reactant documentation section and use the Reactant CLI to quickly build a Reactant application and start your new React app development experience.
Repo:
Github.com/unadlib/rea…