react-coat

Structured React + Redux with Typescript and support for isomorphic rendering beautifully(SSR)

English

  • The framework is React state and data flow management. It does not improve and encapsulate React itself, nor does it violate the style and trend of React FP.
  • The framework uses Class to organize the Model, supports inheritance, but does not force the use of inheritance, sometimes inheritance will increase the complexity of the project.
  • Criticism and correction are welcome. Feedback if there are any mistakes or Bugs. Don’t forget to give a Star if you think it’s good._<
  • Why? Article Recommendation:https://zhuanlan.zhihu.com/p/58583636

The opening, freedom and prosperity of react ecosphere also lead to tedious development and configuration and confused choice.Reaction-coat abandons some flexibility, replaces some configurations with conventions, solidifies some best practices, and provides developers with a more concise sugar coat.

Are you still honestly maintaining the store according to the native Redux tutorial?Try react-coat, which is so simple that you can do it almost without learning.

For example:

//  Only one class, action、reducer、effect、loading
class ModuleHandlers extends BaseModuleHandlers {
  @reducer
  protected putCurUser(curUser: CurUser): State {
    return {...this.state, curUser};
  }
  @reducer
  public putShowLoginPop(showLoginPop: boolean): State {
    return {...this.state, showLoginPop};
  }
  @effect("login") // use loading state
  public async login(payload: {username: string; password: string}) {
    const loginResult = await sessionService.api.login(payload);
    if (!loginResult.error) {
      // this.updateState() is a shortcut to this.dispatch(this.actions.updateState())
      this.updateState({curUser: loginResult.data});
      Toast.success("welcome!");
    } else {
      Toast.fail(loginResult.error.message);
    }
  }
  // uncatched error will dispatch @@framework/ERROR action
  // subscribe it and reporting to the server
  @effect(null) // set null that means loading state are not needed
  protected async ["@@framework/ERROR"](error: CustomError) {
    if (error.code === "401") {
      // dispatch action: putShowLoginPop
      this.dispatch(this.actions.putShowLoginPop(true));
    } else if (error.code === "301" || error.code === "302") {
      // dispatch action: router change
      this.dispatch(this.routerActions.replace(error.detail));
    } else {
      Toast.fail(error.message);
      await settingsService.api.reportError(error);
    }
  }
  // subscribe itself's INIT Action and to do any async request
  @effect()
  protected async ["app/INIT"]() {
    const [projectConfig, curUser] = await Promise.all([
      settingsService.api.getSettings(),
      sessionService.api.getCurUser()
    ]);
    // this.updateState() is a shortcut to this.dispatch(this.actions.updateState())
    this.updateState({
      projectConfig,
      curUser,
    });
  }
}

Static checking and intelligent prompts with Typescript:

TS Types

Subscribe to the Newsletter

Get our latest news,tutorials,guides,tips & deals delivered to your inbox.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

shares