zoukankan      html  css  js  c++  java
  • React JS: 如何使用 RxService 管理状态

    快速使用 vite 创建一个react-ts项目

    λ npm init vite@latest
    npx: 6 安装成功,用时 2.033 秒
    √ Project name: ... myapp
    √ Select a framework: » react
    √ Select a variant: » react-ts
    
    λ cd myapp
    λ npm install
    

    下载 rxjs 和 react-rxbuilder

    λ npm i rxjs react-rxbuilder
    

    使用编辑器向 tsconfig.json 添加两项,用于支持装饰器语法和Metadata元数据

    {
      "compilerOptions": {
    
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
    
      },
    }
    

    在根组件挂载 RxService

    import { RxService } from "react-rxbuilder";
    
    ReactDOM.render(
      <React.StrictMode>
    
        <RxService>{() => <App />}</RxService>
    
      </React.StrictMode>,
      document.getElementById("root")
    );
    

    通常你只需要在你的程序中使用一次 RxService

    在 App 组件中创建 Service

    import { Injectable } from "react-rxbuilder";
    
    @Injectable()
    class CountService {
      i = 0;
      inc() {
        this.i++;
      }
    }
    

    使用 Injectable 将一个类快速注册为 Service

    在组件中使用 CountService

    function App() {
      const [count] = useService(CountService);
      return (
        <>
          <h2>{count.i}</h2>
          <button onClick={count.inc}>Inc</button>
        </>
      );
    }
    

    现在你的 App.tsx 文件应该是这样

    import React from "react";
    import { Injectable, useService } from "react-rxbuilder";
    
    @Injectable()
    class CountService {
      i = 0;
      inc() {
        this.i++;
      }
    }
    
    function App() {
      const [count] = useService(CountService);
      return (
        <>
          <h2>{count.i}</h2>
          <button onClick={count.inc}>Inc</button>
        </>
      );
    }
    
    export default App;
    

    启动开发服务器,然后在页面中点击 button 看看

    λ npm run dev
    

    在组件中使用多个 Service

    继续使用 Injectable 创建 LogService

    @Injectable()
    class LogService {
      log() {
        console.log(new Date().toLocaleString());
      }
    }
    

    然后在 App 组件中使用

    function App() {
      const [count, log] = useService(CountService, LogService);
      return (
        <>
          <h2>{count.i}</h2>
          <button onClick={() => (count.inc(), log.log())}>
            Inc
          </button>
        </>
      );
    }
    

    现在点击按钮的同时,在控制台记录消息


    为了简化代码,我们可以在 CountService 中使用 LogService

    @Injectable()
    class CountService {
    
      constructor(public readonly logService: LogService) {}
    
      i = 0;
      inc() {
        this.i++;
        this.logService.log();
      }
    }
    

    上面使用了 constructor 依赖注入,但是你打开服务器可能会遇到 this.logService 是 undefined 的错误,因为 vite 使用的是 esbuild 可以使用 swc代替 esbuild

    还有一种解决方案是使用静态属性代替 constructor 依赖注入

    最后的代码如下

    import React from "react";
    import { Injectable, useService } from "react-rxbuilder";
    
    @Injectable()
    class LogService {
      static ins: LogService;
      log() {
        console.log(new Date().toLocaleString());
      }
    }
    
    @Injectable()
    class CountService {
      readonly logService = LogService.ins;
      
      i = 0;
      inc() {
        this.i++;
        this.logService.log();
      }
    }
    
    function App() {
      const [count] = useService(CountService);
      return (
        <div>
          <h2>{count.i}</h2>
          <button onClick={count.inc}>Inc</button>
        </>
      );
    }
    
    export default App;
    
  • 相关阅读:
    Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录
    android启动界面
    ubuntu 关于sublime text3的一些应用
    [LeetCode]Valid Sudoku解题记录
    在 Mac OS X 10.10 安装 pyenv 的一个小坑
    java调用百度地图API依据地理位置中文获取经纬度
    debug openStack
    error recoder,error debug for openStack kilo
    SDN,NFV
    openStack kilo 手动Manual部署随笔记录
  • 原文地址:https://www.cnblogs.com/ajanuw/p/15074557.html
Copyright © 2011-2022 走看看