1.1.5 • Published 4 years ago

hooxus v1.1.5

Weekly downloads
1
License
MIT
Repository
github
Last release
4 years ago

English

Hooxus —— A small tool library for react hooks

Hooxus = Hooks + Nexus

It means -- connect react hooks

The purposes Hooxi are as follows:

  1. Using the React-node-tree as the carrier of data management (instead of custom state tree)
  2. Modularity,serve for data-driven design and Domain Driven Design Support
  3. Less is more

Use

npm install hooxus

Core API —— useData

const data = useData({
  name:'',
  password:''
})

Declare an object, pass in useData

That object is reactive, which means you don't need to distinguish every setter and getter of'em, just use it directly:

<input value={data.name} onChange={e=>{ data.name = e.target.value }}/>

// !! data.name = e.target.value

Just treat it as a normal object, because hooxus will automatically help you deal with reactive problems!

Notion: only object can be passed in!

Modularity—— Service

After determining the usage, how to deal with data transfer and sharing problems among multiple components?

Hooxus proposed modularization scheme(extracted as service layer) ——

export const nameService= createService({ name:'' })

function Test(){
  const data = nameService.inject()
}

export default AttachServices(Test, [nameService]);
  • createService:Creating a service that each component can inject into
  • Service.inject():Inject
  • AttachServices(Component,...Services):Services can be use for all the components and their component trees

When sub components or sub components are used, only service.inject is needed:

import { nameService } from 'Test'
function Child(){
  const data = nameService.inject()
}

Scheduling function —— useDebounce,useTrottle,useTake

There are three APIs that give you some control over reactivity:

const value = useData({name:'', password:''})
const changeAfter = useDebounce(value, 1000)
// Change every 1000 ms
const changeWthin = useThrottle(value, 1000)
// Change only once in 1000 ms
const changeHistory = useTake(value, 3)
// Array records the last three data changes

Notion:Map and other transformation functions in previous version are no longer provided. The current version is convenient for data transformation

Module internal logic

You can define functions in the service and change data through this directly:

const nameService = createService({
  name:'',
  async getNameFromBackend(){
    const nameFromBack = await fetch(/* ... */)
    this.name = name //  or returned directly and assigned in the component
  }
}) 

Example

import { createService, AttachServices, useDebounce } from "hooxus";

const formService = createService({
  name: "",
  password: "",
  submit() {
    console.log("submit");
  }
});

function App() {
  const formData = formService.inject();
  const formDataDebounced = useDebounce(formData, 1000);
  // validate
  const nameValid = formDataDebounced.name.length <= 10;
  const passwordValid = formDataDebounced.password.length <= 10;
  const valid = nameValid && passwordValid;

  return (
    <div>
      <p>
        <input
          value={formData.name}
          {/* Direct assignment formData.name = xxx */}
          onChange={e => {formData.name = e.target.value}}
        />
        <span>{nameValid ? "" : "Length cannot exceed 10"}</span>
      </p>
      <p>
        <input
          value={formData.password}
          onChange={e => {formData.password = e.target.value}}
        />
        <span>{passwordValid ? "" : "Length cannot exceed 10"}</span>
      </p>
      <button
        disabled={!valid}
        onClick={() => {
          formData.submit();
        }}
      >
        Submit
      </button>
    </div>
  );
}

export default AttachServices(App, [formService]);

Happy hacking~

简体中文

Hooxus —— 一个面向 React Hooks 的小型工具库

Hooxus = Hooks + Nexus

意思是 —— 将 React Hooks 连接起来

Hooxus 的宗旨如下:

  1. 利用 React 节点树作为数据管理的载体 (而并非自定义状态树)
  2. 提供模块化能力,提供数据驱动设计和领域驱动设计支持
  3. 少即是多,API 面积很小

使用

npm install hooxus

核心API —— useData

const data = useData({
  name:'',
  password:''
})

声明一个对象,传入 useData

这个对象是响应式的,意味着你不需要区分 setter 和 getter,直接使用即可:

<input value={data.name} onChange={e=>{ data.name = e.target.value }}/>

// !! data.name = e.target.value

你只需要将其作为正常对象即可,Hooxus 会自动帮你处理响应式问题!

注:只能传入对象!

模块化 —— Service

确定使用风格之后,如何处理组件间数据传递和共享呢?

Hooxus 提出了模块化的方案(提取为 Service 层) ——

export const nameService= createService({ name:'' })

function Test(){
  const data = nameService.inject()
}

export default AttachServices(Test, [nameService]);
  • createService:负责创建一个各组件可以注入的 Service
  • Service.inject():将 Service 注入组件内部
  • AttachServices(Component,...Services):该 Service 对所有该组件及其组件树有效

子组件或者孙组件使用时,只需要 Service.inject 即可:

import { nameService } from 'Test'
function Child(){
  const data = nameService.inject()
}

调度函数 —— useDebounce,useTrottle,useTake

有三个 API 提供给您一定的对响应式的掌控力:

const value = useData({name:'', password:''})
const changeAfter = useDebounce(value, 1000)
// 每隔 1000 ms 后改变一次
const changeWthin = useThrottle(value, 1000)
// 1000 ms 内只改变一次
const changeHistory = useTake(value, 3)
// 数组记录最近三次数据变化

注:不再提供上一版本的 map 等变换函数,当前版本可以很方便实现数据变换

模块内部逻辑

可以在 Service 内定义函数,通过 this 改变数据:

const nameService = createService({
  name:'',
  async getNameFromBackend(){
    const nameFromBack = await fetch(/* ... */)
    this.name = name // 亦可直接返回,在组件内进行赋值
  }
}) 

例子

import { createService, AttachServices, useDebounce } from "hooxus";

const formService = createService({
  name: "",
  password: "",
  submit() {
    console.log("submit");
  }
});

function App() {
  const formData = formService.inject();
  // 防抖
  const formDataDebounced = useDebounce(formData, 1000);
  // 验证
  const nameValid = formDataDebounced.name.length <= 10;
  const passwordValid = formDataDebounced.password.length <= 10;
  const valid = nameValid && passwordValid;

  return (
    <div>
      <p>
        <input
          value={formData.name}
          {/* 直接赋值 formData.name = xxx */}
          onChange={e => {formData.name = e.target.value}}
        />
        <span>{nameValid ? "" : "长度不能超过 10"}</span>
      </p>
      <p>
        <input
          value={formData.password}
          onChange={e => {formData.password = e.target.value}}
        />
        <span>{passwordValid ? "" : "长度不能超过 10"}</span>
      </p>
      <button
        disabled={!valid}
        onClick={() => {
          formData.submit();
        }}
      >
        提交
      </button>
    </div>
  );
}

export default AttachServices(App, [formService]);

欢迎使用和指正~

1.1.5

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago

1.1.4

4 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.0.2

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.3

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.4.5

4 years ago

0.4.4

4 years ago

0.4.3

4 years ago

0.4.2

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.9

4 years ago

0.3.8

4 years ago

0.3.7

4 years ago

0.3.6

4 years ago

0.3.5

4 years ago

0.3.4

4 years ago

0.3.3

4 years ago

0.3.2

4 years ago

0.3.1

4 years ago

0.3.0

4 years ago

0.2.0

4 years ago

0.1.9

4 years ago

0.1.8

4 years ago

0.1.7

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.4

4 years ago