Skip to content

Commit

Permalink
Merge pull request #12 from llq0802/dev
Browse files Browse the repository at this point in the history
完成rc-use-hooks的阿帕奇版本
  • Loading branch information
llq0802 authored Oct 27, 2022
2 parents 7daa7d5 + bb10df7 commit 4e8ac49
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 16,869 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
]
},
"dependencies": {
"antd": "^4.23.5",
"react": "17.0.2"
"antd": "^4.23.6"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.15.1",
Expand All @@ -56,4 +55,4 @@
"workspaces": [
"packages/*"
]
}
}
2 changes: 1 addition & 1 deletion packages/rc-use-hooks/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 doly-dev
Copyright (c) 2022 llq0802

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion packages/rc-use-hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export { default as useResetState } from './useResetState';
export { default as useSafeState } from './useSafeState';
export { default as useSetState } from './useSetState';
export { default as useShow } from './useShow';
export type { OnShowInstance } from './useShow';
export type { UseShowInstance, UseShowInstanceRef, UseShowOptions } from './useShow';
export { default as useThrottleFn } from './useThrottleFn';
export { default as useUnmounted } from './useUnmounted';
export { default as useUpdated } from './useUpdated';
2 changes: 1 addition & 1 deletion packages/rc-use-hooks/src/useConcurrentRequest/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ nav:

# useConcurrentRequest

并发请求函数 请求结果数组顺序同参数数组顺序一致
并发请求函数,支持设置最大并发数, 请求结果数组顺序同参数数组顺序一致

## 代码演示

Expand Down
4 changes: 2 additions & 2 deletions packages/rc-use-hooks/src/useLockAsyncFn/demos/demo1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function mockRequest() {

export default () => {
const [count, setCount] = useState(0);
const submit = useLockAsyncFn(async (params) => {
const { run, loading } = useLockAsyncFn(async (params) => {
message.info(`开始请求${params}`);
await mockRequest();
setCount((val) => val + 1);
Expand All @@ -27,7 +27,7 @@ export default () => {
return (
<>
<p>请求次数: {count}</p>
<Button onClick={() => submit('99')}>Submit</Button>
<Button onClick={() => run('99')}>Submit</Button>
</>
);
};
2 changes: 1 addition & 1 deletion packages/rc-use-hooks/src/useLockAsyncFn/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ nav:

# useLockAsyncFn

用于给一个异步函数增加竞态锁,防止并发执行。
用于给一个异步函数增加节流阀,防止并发执行。

## 代码演示

Expand Down
12 changes: 10 additions & 2 deletions packages/rc-use-hooks/src/useLockAsyncFn/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import { useCallback, useRef } from 'react';
import { useCallback, useRef, useState } from 'react';

/**
* 用于给一个异步函数节流阀,防止并发执行。
*/
export default function useLockAsyncFn<P extends any[] = any[], V extends any = any>(
fn: (...args: P) => Promise<V>,
) {
const [loading, setLoading] = useState<boolean>(false);
const lockRef = useRef<boolean>(false);

return useCallback(
const run = useCallback(
async (...args: P) => {
if (lockRef.current) return;
lockRef.current = true;
try {
setLoading(true);
const ret = await fn(...args);
setLoading(false);
lockRef.current = false;
return ret;
} catch (e) {
setLoading(false);
lockRef.current = false;
throw e;
}
},
[fn],
);
return {
loading,
run,
};
}

// // 防止网络请求多次(使用promise实现)
Expand Down
34 changes: 24 additions & 10 deletions packages/rc-use-hooks/src/useShow/demos/demo1.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Button, Checkbox, Form, Input, message, Modal, Space } from 'antd';
import type { OnShowInstance } from 'rc-use-hooks';
import type { UseShowInstance, UseShowInstanceRef } from 'rc-use-hooks';
import { useShow } from 'rc-use-hooks';
import type { RefObject } from 'react';
import { useRef, useState } from 'react';

const demo1 = () => {
const childModelRef = useRef<OnShowInstance>(null);
const childModelRef = useRef<UseShowInstance>(null);

const handleClickShow = () => {
childModelRef.current?.onShow({
Expand All @@ -16,21 +15,22 @@ const demo1 = () => {
};
const handleClickHide = () => {
childModelRef.current?.onHide({
name: '李岚清',
age: 25,
remember: true,
name: '吴彦祖',
age: 18,
remember: false,
});
};

const handleGetData = () => {
const childData = childModelRef.current?.getChildData();

message.info(`子组件数据为: ${JSON.stringify(childData, null, 2)}`);
message.info(`获得到子组件数据为: ${JSON.stringify(childData, null, 2)}`);
console.log(' childData', childData);
};

return (
<div>
<div style={{ border: '1px solid #888', padding: 20 }}>
<h2>这是父组件</h2>
<Space>
<Button onClick={handleClickShow}> 父组件调用onShow事件并传参数给子组件</Button>
<Button onClick={handleClickHide}> 父组件调用onHide事件并传参数给子组件</Button>
Expand All @@ -45,18 +45,21 @@ const demo1 = () => {
export default demo1;

type ChildModelProps = {
funcRef: RefObject<OnShowInstance>;
funcRef: UseShowInstanceRef;
};
function ChildModel({ funcRef }: ChildModelProps) {
const [open, setOpen] = useState(false);

const { parentData, setParentData } = useShow(funcRef, {
onShow: (data: Record<string, any>) => {
message.info(`父组件调用了onShow并传参数${JSON.stringify(data, null, 2)}`);
console.log('父组件调用了onShow并传参数 ', data);
setOpen(true);
},

onHide: (data) => {
message.info(`父组件调用了onHide并传参数${JSON.stringify(data, null, 2)}`);

console.log('父组件调用了onHide并传参数 ', data);
setOpen(false);
},
Expand All @@ -70,9 +73,20 @@ function ChildModel({ funcRef }: ChildModelProps) {
setOpen(false);
};

const handleCancel = () => {
setParentData(null);
setOpen(false);
};

return (
<>
<Modal open={open} title="子组件的弹窗" onOk={handleOk} onCancel={() => setOpen(false)}>
<Modal
open={open}
title="这是子组件弹窗"
onOk={handleOk}
onCancel={handleCancel}
okText="点我向父组件传数据"
>
<Form
name="basic"
labelCol={{ span: 5 }}
Expand Down
69 changes: 40 additions & 29 deletions packages/rc-use-hooks/src/useShow/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ nav:

# useShow

父组件通过 ref 唤起子组件、用于业务功能代码分离、避免过多状态和业务代码集中在一个文件上。
父组件通过 ref 唤起子组件 _(包括兄弟组件)_、用于业务功能代码分离、避免过多状态和业务代码集中在一个文件上。

基于 useImperativeHandle、可以相互传参。各组件拥有独立的状态、`状态更新也不会造成其他组件重复执行`
基于 `useImperativeHandle`、可以相互传参。各组件拥有独立的状态、`状态更新也不会造成其他组件重复执行`

## 代码演示

Expand All @@ -22,53 +22,64 @@ nav:

## API

```typescript
//父组件
const funRef = useRef<OnShowInstance>(null);
funRef.current?.onShow({name:'李岚清',age:'25})
<ChildModel funcRef={funRef} />;

//子组件

const { parentData, setParentData } = useShow(funcRef, {
onShow: (data: Record<string, any>) => {
console.log('父组件调用了onShow并传参数 ', data); // {name:'李岚清',age:'25}
},
});
```
### 父组件调用

```ts
const funRef = useRef<OnShowInstance>(null);
funRef.current?.onShow(data); // 触发子组件方法onShow
funRef.current?.onHide(); // 触发子组件方法onHide
funRef.current?.getChildData(); // 获取子组件数据

<ChildModel funcRef={funRef} />;
```

### 子组件调用

```ts
/**
* record 父组件传给子组件的参数
* onCallback 子组件执行方法,往ref存放数据、父组件使用getData获取数据
* parentData 父组件传给子组件的参数
* setParentData 子组件执行方法,往内部ref存放数据、父组件使用getChildData函数获取子组件数据
**/
const { parentData, setParentData } = useShow(funRef, {
onShow: () => void, // 父组件执行onShow的时候触发
onHide: () => void, // 父组件执行onShow的时候触发
onFormart: (data:Record<string,any>) => any, // 格式化父组件调用onShow传入的参数
onShow: (parentData: Record<string, any>) => void, // 父组件执行onShow的时候触发
onHide: (parentData: Record<string, any>) => void, // 父组件执行onShow的时候触发
onFormart: (parentData:Record<string,any>) => any, // 格式化父组件调用onShow传入的参数
});
```

### Params

| 参数 | 说明 | 类型 | 默认值 |
| ----- | ---------- | ---- | ------ |
| state | state 的值 | - | - |
| 参数 | 说明 | 类型 |
| :-----: | :------------------: | :----------------------: |
| funRef | 从父组件传过来的 ref | `UseShowInstance` |
| options | 配置参数 | ` UseShowOptions<T=any>` |

### Result

| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| setState | 第一个参数传入新的 state,第二个参数为回调函数接受最新传入的 state | (newState: SetStateAction<T>, cb: (newState: T) => void) => void; | - |
| 参数 | 说明 | 类型 |
| ------------------------- | ------------------------------------------------ | --------------- |
| `{parentData,parentData}` | 父组件调用 onShow 传入的数据与穿给组件数据的方法 | `UseShowResult` |

### OnShowInstance
```ts
type UseShowInstance<T = any> = {
onShow: (record: T) => void;
onHide: (data?: any) => void;
getChildData: () => any;
};

type UseShowInstanceRef<T = any> = RefObject<UseShowInstance<T>>;

type UseShowOptions<T> = {
/** show触发事件 */
onShow: (data: T) => void;
/** 格式化data */
onFormart?: (data: T) => T;
/** hide触发事件 */
onHide?: (data?: any) => void;
};

type UseShowResult = {
parentData: Record<string, any>;
setParentData: <T = any>(data: T) => void;
};
```
26 changes: 13 additions & 13 deletions packages/rc-use-hooks/src/useShow/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ import _cloneDeep from 'lodash/cloneDeep';
import type { RefObject } from 'react';
import { useCallback, useImperativeHandle, useRef } from 'react';

export declare type OnShowInstance<T = any> = {
export declare type UseShowInstance<T = any> = {
onShow: (record: T) => void;
onHide: (data?: any) => void;
getChildData: () => any;
};

export declare type ShowInstanceRef<T = any> = RefObject<OnShowInstance<T>>;
export declare type UseShowInstanceRef<T = any> = RefObject<UseShowInstance<T>>;

export declare type OnShowOptionsType<T> = {
export declare type UseShowOptions<T> = {
/** show触发事件 */
onShow: (record: T) => void;
/** 格式化record */
onFormart?: (record: T) => T;
onShow: (data: T) => void;
/** 格式化data */
onFormart?: (data: T) => T;
/** hide触发事件 */
onHide?: (data?: any) => void;
};

export declare type R = {
export declare type UseShowResult = {
parentData: Record<string, any>;
setParentData: <T = any>(data: T) => void;
};
Expand All @@ -31,10 +31,10 @@ export declare type R = {
* @returns T 传输的数据
*/
export default function useShow(
funcRef: ShowInstanceRef,
options: OnShowOptionsType<Record<string, any>>,
): R {
const ref = useRef({});
funcRef: UseShowInstanceRef,
options: UseShowOptions<Record<string, any>>,
): UseShowResult {
const ref = useRef<null | any>(null);
const childrenDataRef = useRef<null | any>(null);
const opsOnShow = options.onShow,
opsOnFormart = options.onFormart,
Expand All @@ -46,8 +46,8 @@ export default function useShow(

useImperativeHandle(funcRef, () => {
return {
onShow: function (record) {
ref.current = _cloneDeep(record);
onShow: function (data) {
ref.current = _cloneDeep(data);
if (opsOnShow) opsOnShow(ref.current);
},

Expand Down
Loading

0 comments on commit 4e8ac49

Please sign in to comment.