theme: juejin
react-hooks-zhuan
砌墙需要砖,这个 hooks 就是 react 的一块砖,想往哪搬往哪搬,基于 react18, typescript
Install
xxx add @aotoo/react-hooks-zhuan
基础用法
Item 用法
import { useItem } from '@aotoo/react-hooks-zhuan';
const [ref, ItemUI] = useItem({ title: 'hello' });
return <ItemUI />;
List 用法
List 组件是 Item 组件的集合
import { useList } from '@aotoo/react-hooks-zhuan';
const [ref, ListUI] = useItem({ data: [{ title: 'hello' }, { title: 'world' }] });
React.useEffect(() => {
setTimeout(() => {
ref.current.append({ title: '我是一块砖' });
}, 2000);
}, []);
return <ListUI />;
事件绑定
react-hooks-zhuan
扩展了 react 的事件对象,支持三个参数 event, param, ref
,event 为 react 原生事件对象,param 参数暂时没有定义,默认值为{},ref 则为操作对象的实例
import { useItem } from '@aotoo/react-hooks-zhuan';
const [ref, ItemUI] = useItem({
title: 'hello',
onClick(e, param, ItemRef) {
ItemRef.current.addClass('active');
},
});
return <ItemUI />; // 也可直接配置 <ItemUI onClick={...}>
子结构
import { useItem } from '@aotoo/react-hooks-zhuan';
const [ref, ItemUI] = useItem({
title: 'hello',
bodyClass: 'body-class-name',
body: [
{ title: 'body item 1', className: 'body-item' },
{
title: 'body item 2',
onClick(e, param, btRef) {
btRef.current.hide();
},
},
],
});
return <ItemUI />;
嵌套结构
import { useItem } from '@aotoo/react-hooks-zhuan';
const [ref, ItemUI] = useItem({
title: 'hello',
bodyClass: 'body-class-name',
body: [
{title: 'body item 1', className: 'body-item'},
{
title: 'body item 2',
body: [
{title: 'body item 3', body: [...]}
{title: 'body item 4', onClick(e, param, btRef){
btRef.current.hide()
}}
]
}
]
});
return <ItemUI />;
All Hooks
- useItem(param: ItemProps):
基础 Item 钩子,包含各种钩子的方法,会在内存中注册实例 - useList({data: Array<ItemProps>, className, style}):
基础 List 钩子,包含各种钩子的方法,会在内存中注册实例 - usePureItem(param: ItemProps):
输出纯的 Item 组件结构 - usePureList({data: Array<ItemProps>, className, style}):
输出纯的 List 组件结构
Item 组件配置属性
完整的 Item 组件包含 body, footer, dot, titles
数组子结构,可通过配置实现项目需求结构。其中body, footer, titles
会包裹一层 div,支持控制样式,数据,显示,隐藏等方法。dot
较为特殊,它的子元素将作为父级的直接子元素,方便定制那些有浮动需求的结构
ItemProps
Item 组件的配置项
interface ItemProps {
title?: React.ReactNode | Array<ItemProps>;
className?: string;
style?: {};
img?: string | string[] | IImg | Array<IImg>;
url?: string | IUrl;
attr?: {};
// 子容器
body?: Array<React.ReactNode | ItemProps>;
footer?: Array<React.ReactNode | ItemProps>;
dot?: Array<React.ReactNode | ItemProps>;
// 子容器属性
titleClass?: string;
titleStyle?: {};
titleProps?: {};
bodyClass?: string;
bodyStyle?: {};
bodyProps?: {};
footerClass?: string;
footerStyle?: {};
footerProps?: {};
}
titles 结构
没有专门的 titles 属性相对应,直接将 title 属性定义为数组即可
const [ref, ItemUI] = useItem({
title: [{ title: '标题' }],
body: [{ title: 'body title' }],
});
上例中我们同时设定了 titles、body 两组结构
实例方法
使用useItem, useList
创建的结构,会在内存中注册该组件的链状数据,这些实例包含以下方法
Item 实例方法
type ItemRef = {
getData: () => ItemProps,
getClassName: () => string,
addClass: (className: string, cb?: () => void) => void,
removeClass: (className: string, cb?: () => void) => void,
hasClass: (className: string) => boolean,
toggleClass: (className: string, cb?: () => void) => void,
css: (style: object) => void,
show: () => void,
hide: () => void,
update: (cb: (partsData) => Array<ItemProps>) => void,
updateContent: (param: Pick<ItemProps, 'title' | 'img' | 'url'>) => void,
children: (className: string | number) => Array<ItemRef>,
parent: (className: string | number) => Array<ItemRef>,
siblings: (className: string) => Array<ItemRef>,
remove: () => void,
getUniqId: () => string,
getData: () => Array<ItemProps>,
// 子容器实例
body?: PartsRefProps,
footer?: PartsRefProps,
titles?: PartsRefProps,
dot?: Pick<PartsRefProps, 'update' | 'children'>,
};
查找父子组件
// 一级子组件
const childs = itemRef.current.children(1);
// 所有子组件,子组件中的嵌套子组件都将返回
const childs = itemRef.current.children();
// 查找指定样式子组件
const childs = itemRef.current.children('class-name');
// 一级父组件
const parent = itemRef.current.parent(1);
// 所有父级组件
const parents = itemRef.current.parent();
// 查找指定样式的父级组件
const parents = itemRef.current.parent('class-name');
Item 组件更新
全局更新会触发所有子结构渲染,请注意使用
itemRef.current.update((state)=>{
const newState = {...state, ......}
return newState
})
子结构实例方法
在 Item 实例中包含 body, footer, dot, titles 子结构,它们有自己的执行方法,这提升了渲染精度,不会导致大面积更新结构
type PartsRefProps = {
getClassName: () => string,
addClass: (className: string, cb?: () => void) => void,
removeClass: (className: string, cb?: () => void) => void,
hasClass: (className: string) => boolean,
toggleClass: (className: string, cb?: () => void) => void,
css: (style: object) => void,
show: () => void,
hide: () => void,
update: (cb: (partsData) => Array<BodyProps | FooterProps | TitlesProps | DotProps>) => void,
children: () => Array<ItemRef>,
};
子组件更新
全局更新会触发所有 body 内子结构渲染,请注意使用
itemRef.current.body.update((state)=>{
const newState = {...state, ......}
return newState
})
List 实例方法
type ListRef = {
getData: () => Array<ItemProps>,
getClassName: () => string,
addClass: (className: string, cb?: () => void) => void,
removeClass: (className: string, cb?: () => void) => void,
hasClass: (className: string) => boolean,
toggleClass: (className: string, cb?: () => void) => void,
css: (style: object) => void,
show: () => void,
hide: () => void,
getUniqId: () => string,
update: (cb: (partsData) => Array<ItemProps>) => void,
children: (className: string | number) => Array<ItemRef>,
parent: (className: string | number) => Array<ItemRef>,
remove: () => void,
append: (param: ItemProps) => void,
prepend: (param: ItemProps) => void,
delete: (uid: string | number) => void,
keys: () => Array<{
id: string,
uniqId: string,
title: string | number | ItemProps | ItemProps[] | React.ReactElement,
attr: {},
}>,
};
List 组件更新
全局更新会触发所有子结构渲染,请注意使用
listRef.current.update(({data})=>{
const newData = {...data, ......}
return newData
})