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;
    
  • 相关阅读:
    173. Binary Search Tree Iterator
    199. Binary Tree Right Side View
    230. Kth Smallest Element in a BST
    236. Lowest Common Ancestor of a Binary Tree
    337. House Robber III
    449. Serialize and Deserialize BST
    508. Most Frequent Subtree Sum
    513. Find Bottom Left Tree Value
    129. Sum Root to Leaf Numbers
    652. Find Duplicate Subtrees
  • 原文地址:https://www.cnblogs.com/ajanuw/p/15074557.html
Copyright © 2011-2022 走看看