hooxus
v1.1.5
Published
react hooks tools
Downloads
25
Maintainers
Readme
English
Hooxus —— A small tool library for react hooks
Hooxus = Hooks + Nexus
It means -- connect react hooks
The purposes Hooxi are as follows:
- Using the React-node-tree as the carrier of data management (instead of custom state tree)
- Modularity,serve for data-driven design and Domain Driven Design Support
- 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 的宗旨如下:
- 利用 React 节点树作为数据管理的载体 (而并非自定义状态树)
- 提供模块化能力,提供数据驱动设计和领域驱动设计支持
- 少即是多,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]);
欢迎使用和指正~