File tree Expand file tree Collapse file tree 4 files changed +123
-0
lines changed Expand file tree Collapse file tree 4 files changed +123
-0
lines changed Original file line number Diff line number Diff line change
1
+ /**
2
+ * title: 将 state 持久化在 localStorage 中
3
+ * desc: 刷新页面后,可以看到输入框中的内容被从 localStorage 中恢复了。
4
+ */
5
+
6
+ import type { FunctionComponent } from 'react' ;
7
+ import { useRef } from 'react' ;
8
+ import { Space , Input } from 'antd' ;
9
+ import 'antd/dist/antd.css' ;
10
+ import { useSize } from '..' ;
11
+
12
+ const Component : FunctionComponent = ( ) => {
13
+ const elRef = useRef ( null ) ;
14
+ const size = useSize ( elRef ) ;
15
+
16
+ return (
17
+ < >
18
+ < Space direction = "vertical" >
19
+ < Space >
20
+ < span > 宽:{ size . width } </ span >
21
+ < span > 高:{ size . height } </ span >
22
+ </ Space >
23
+ < Input . TextArea ref = { elRef } />
24
+ </ Space >
25
+ </ >
26
+ ) ;
27
+ } ;
28
+
29
+ export default Component ;
Original file line number Diff line number Diff line change
1
+ import { useLayoutEffect , useState } from 'react' ;
2
+ import type { BasicTarget } from '../utils/dom' ;
3
+ import { getTargetElement } from '../utils/dom' ;
4
+
5
+ type Size = {
6
+ width ?: number ;
7
+ height ?: number ;
8
+ } ;
9
+
10
+ export function useSize ( target : BasicTarget ) {
11
+ const [ size , setSize ] = useState < Size > ( ( ) => {
12
+ const el = ( getTargetElement ( target ) || { } ) as HTMLElement ;
13
+ return {
14
+ width : el . clientWidth ,
15
+ height : el . clientHeight ,
16
+ } ;
17
+ } ) ;
18
+
19
+ useLayoutEffect ( ( ) => {
20
+ const el = getTargetElement ( target ) ;
21
+ if ( ! el ) {
22
+ return ;
23
+ }
24
+
25
+ const resizeObserver = new ResizeObserver ( ( entries ) => {
26
+ entries . forEach ( ( entry ) => {
27
+ setSize ( {
28
+ width : entry . target . clientWidth ,
29
+ height : entry . target . clientHeight ,
30
+ } ) ;
31
+ } ) ;
32
+ } ) ;
33
+ resizeObserver . observe ( el as Element ) ;
34
+
35
+ // eslint-disable-next-line consistent-return
36
+ return ( ) => resizeObserver . disconnect ( ) ;
37
+ } , [ target ] ) ;
38
+
39
+ return size ;
40
+ }
Original file line number Diff line number Diff line change
1
+ ---
2
+ title : useSize
3
+ nav :
4
+ title : Hooks
5
+ path : /hook
6
+ order : 2
7
+ ---
8
+
9
+ # useSize
10
+
11
+ 监听 dom 元素尺寸变化的 hook
12
+
13
+ <code src =" ./demo/useSize.tsx " >
14
+
15
+ # API
16
+
17
+ ``` typescript
18
+ const size = useSize (dom );
19
+ ```
20
+
21
+ # 返回值
22
+
23
+ | 参数 | 说明 | 类型 |
24
+ | ---- | ------ | --------------------------------- |
25
+ | size | 尺寸值 | {width?: number, height?: number} |
Original file line number Diff line number Diff line change
1
+ import type { MutableRefObject } from 'react' ;
2
+
3
+ type TargetElement = HTMLElement | Element | Document | Window ;
4
+
5
+ export type BasicTarget < T = HTMLElement > =
6
+ | T
7
+ | null
8
+ | ( ( ) => T | null )
9
+ | MutableRefObject < T | null | undefined > ;
10
+
11
+ export function getTargetElement (
12
+ target ?: BasicTarget < TargetElement > ,
13
+ defaultTarget ?: TargetElement ,
14
+ ) : TargetElement | undefined | null {
15
+ if ( ! target ) {
16
+ return defaultTarget ;
17
+ }
18
+
19
+ let targetElement : TargetElement | undefined | null ;
20
+ if ( typeof target === 'function' ) {
21
+ targetElement = target ( ) ;
22
+ } else if ( 'current' in target ) {
23
+ targetElement = target . current ;
24
+ } else {
25
+ targetElement = target ;
26
+ }
27
+
28
+ return targetElement ;
29
+ }
You can’t perform that action at this time.
0 commit comments