Skip to content

Commit e9bb7ac

Browse files
committed
Remove AtomFamily
1 parent f90b3d3 commit e9bb7ac

File tree

4 files changed

+69
-79
lines changed

4 files changed

+69
-79
lines changed

src/components/DataKeyPair.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Box } from '@mui/material'
22
import { useAtomValue, useSetAtom } from 'jotai'
3-
import { useAtomCallback } from 'jotai/utils'
43
import type { ComponentProps, FC, MouseEvent } from 'react'
54
import { useCallback, useMemo, useState } from 'react'
65

@@ -15,7 +14,7 @@ import {
1514
onChangeAtom,
1615
quotesOnKeysAtom,
1716
rootNameAtom,
18-
setHoverAtomFamily,
17+
setHoverAtom,
1918
valueAtom
2019
} from '../state'
2120
import { useTypeComponents } from '../stores/typeRegistry'
@@ -78,12 +77,7 @@ export const DataKeyPair: FC<DataKeyPairProps> = (props) => {
7877
(value, index) => value === hoverPath.path[index] && nestedIndex ===
7978
hoverPath.nestedIndex)
8079
}, [hoverPath, path, nestedIndex])
81-
const setHover = useAtomCallback(
82-
useCallback((get, set, arg) => {
83-
// eslint-disable-next-line react-hooks/rules-of-hooks
84-
useSetAtom(setHoverAtomFamily(arg))
85-
}, [])
86-
)
80+
const setHover = useSetAtom(setHoverAtom)
8781
const root = useAtomValue(valueAtom)
8882
const [inspect, setInspect] = useInspect(path, value, nestedIndex)
8983
const [editing, setEditing] = useState(false)
@@ -192,7 +186,10 @@ export const DataKeyPair: FC<DataKeyPairProps> = (props) => {
192186
className='data-key-pair'
193187
data-testid={'data-key-pair' + path.join('.')}
194188
sx={{ userSelect: 'text' }}
195-
onMouseEnter={() => setHover({ path, nestedIndex })}
189+
onMouseEnter={
190+
useCallback(() => setHover({ path, nestedIndex }),
191+
[setHover, path, nestedIndex])
192+
}
196193
>
197194
<DataBox
198195
component='span'

src/hooks/useInspect.ts

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,25 @@
11
import { useAtomValue, useSetAtom } from 'jotai'
2-
import { useAtomCallback } from 'jotai/utils'
32
import {
3+
Dispatch,
4+
SetStateAction,
45
useCallback,
56
useEffect,
67
useState
78
} from 'react'
89

910
import {
1011
defaultInspectDepthAtom,
11-
getInspectCacheAtomFamily,
12-
setInspectCacheAtomFamily
12+
getInspectCacheAtom,
13+
setInspectCacheAtom
1314
} from '../state'
1415
import { useIsCycleReference } from './useIsCycleReference'
1516

1617
export function useInspect (path: (string | number)[], value: any, nestedIndex?: number) {
1718
const depth = path.length
1819
const isTrap = useIsCycleReference(path, value)
1920
const defaultInspectDepth = useAtomValue(defaultInspectDepthAtom)
20-
21-
const getInspectCache = useAtomCallback(
22-
useCallback((get, set, arg) => {
23-
// eslint-disable-next-line react-hooks/rules-of-hooks
24-
useAtomValue(getInspectCacheAtomFamily(arg))
25-
}, [])
26-
)
27-
const setInspectCache = useAtomCallback(
28-
useCallback((get, set, arg) => {
29-
// eslint-disable-next-line react-hooks/rules-of-hooks
30-
useSetAtom(setInspectCacheAtomFamily(arg))
31-
}, [])
32-
)
21+
const getInspectCache = useSetAtom(getInspectCacheAtom)
22+
const setInspectCache = useSetAtom(setInspectCacheAtom)
3323
useEffect(() => {
3424
const inspect = getInspectCache({ path, nestedIndex })
3525
if (inspect !== undefined) {
@@ -45,8 +35,8 @@ export function useInspect (path: (string | number)[], value: any, nestedIndex?:
4535
setInspectCache({ path, inspect })
4636
}
4737
}, [defaultInspectDepth, depth, isTrap, nestedIndex, path, getInspectCache, setInspectCache])
48-
const shouldInspect = useAtomValue(getInspectCacheAtomFamily({ path, nestedIndex }))
49-
const [inspect, setOriginal] = useState<boolean>(() => {
38+
const [inspect, set] = useState<boolean>(() => {
39+
const shouldInspect = getInspectCache({ path, nestedIndex })
5040
if (shouldInspect !== undefined) {
5141
return shouldInspect
5242
}
@@ -57,15 +47,12 @@ export function useInspect (path: (string | number)[], value: any, nestedIndex?:
5747
? false
5848
: depth < defaultInspectDepth
5949
})
60-
const setInspect = useAtomCallback(
61-
useCallback((get, set, apply) => {
62-
setOriginal((oldState) => {
63-
const newState = typeof apply === 'boolean' ? apply : apply(oldState)
64-
// eslint-disable-next-line react-hooks/rules-of-hooks
65-
useSetAtom(setInspectCacheAtomFamily(apply))
66-
return newState
67-
})
68-
}, [])
69-
)
50+
const setInspect = useCallback<Dispatch<SetStateAction<boolean>>>((apply) => {
51+
set((oldState) => {
52+
const newState = typeof apply === 'boolean' ? apply : apply(oldState)
53+
setInspectCache({ path, newState, nestedIndex })
54+
return newState
55+
})
56+
}, [nestedIndex, path, setInspectCache])
7057
return [inspect, setInspect] as const
7158
}

src/index.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
} from '@mui/material'
55
import type { Atom } from 'jotai'
66
import { useAtom, useSetAtom } from 'jotai'
7-
import { useAtomCallback } from 'jotai/utils'
87
import type { FC, ReactElement } from 'react'
98
import { useCallback, useEffect, useMemo, useRef } from 'react'
109

@@ -23,9 +22,9 @@ import {
2322
onChangeAtom,
2423
onCopyAtom,
2524
onSelectAtom,
26-
registryTypesAtomFamily,
25+
registryTypesAtom,
2726
rootNameAtom,
28-
setHoverAtomFamily,
27+
setHoverAtom,
2928
valueAtom
3029
} from './state'
3130
import {
@@ -80,32 +79,28 @@ const JsonViewerInner: FC<JsonViewerProps> = (props) => {
8079
} else if (typeof props.theme === 'object') {
8180
setColorspace(props.theme)
8281
}
83-
}, [props.theme])
82+
}, [props.theme, setColorspace])
8483
const onceRef = useRef(true)
8584
const predefinedTypes = useMemo(() => predefined(), [])
85+
const registerTypes = useSetAtom(registryTypesAtom)
8686
if (onceRef.current) {
8787
const allTypes = [...predefinedTypes]
8888
props.valueTypes?.forEach(type => {
8989
allTypes.push(type)
9090
})
91-
useSetAtom(registryTypesAtomFamily(allTypes))
91+
registerTypes(allTypes)
9292
onceRef.current = false
9393
}
9494
useEffect(() => {
9595
const allTypes = [...predefinedTypes]
9696
props.valueTypes?.forEach(type => {
9797
allTypes.push(type)
9898
})
99-
useSetAtom(registryTypesAtomFamily(allTypes))
100-
}, [predefinedTypes, props.valueTypes])
99+
registerTypes(allTypes)
100+
}, [predefinedTypes, props.valueTypes, registerTypes])
101101

102102
const value = useAtom(valueAtom)
103-
const setHover = useAtomCallback(
104-
useCallback((get, set, arg) => {
105-
// eslint-disable-next-line react-hooks/rules-of-hooks
106-
useSetAtom(setHoverAtomFamily(arg))
107-
}, [])
108-
)
103+
const setHover = useSetAtom(setHoverAtom)
109104
return (
110105
<Paper
111106
elevation={0}
@@ -116,7 +111,11 @@ const JsonViewerInner: FC<JsonViewerProps> = (props) => {
116111
userSelect: 'none',
117112
contentVisibility: 'auto'
118113
}}
119-
onMouseLeave={() => setHover(null)}
114+
onMouseLeave={
115+
useCallback(() => {
116+
setHover(null)
117+
}, [setHover])
118+
}
120119
>
121120
<DataKeyPair
122121
value={value}

src/state.ts

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { atom } from 'jotai'
2-
import { atomFamily } from 'jotai/utils'
32

43
import type { JsonViewerState, TypeRegistryState } from './type'
54

@@ -25,36 +24,44 @@ export const inspectCacheAtom = atom<JsonViewerState['inspectCache'] | undefined
2524
export const hoverPathAtom = atom<JsonViewerState['hoverPath'] | undefined>(undefined)
2625
export const registryAtom = atom<TypeRegistryState['registry'] | undefined>(undefined)
2726

28-
export const getInspectCacheAtomFamily = atomFamily(({ path, nestedIndex }) => {
29-
const target = nestedIndex === undefined
30-
? path.join('.')
31-
: `${path.join('.')}[${nestedIndex}]nt`
32-
return atom((get) => get(inspectCacheAtom)[target])
33-
})
34-
export const setInspectCacheAtomFamily = atomFamily(({ path, action, nestedIndex }) => atom((get, set) => {
35-
const target = nestedIndex === undefined
36-
? path.join('.')
37-
: `${path.join('.')}[${nestedIndex}]nt`
38-
const inspectCache = get(inspectCacheAtom)
39-
return set(inspectCacheAtom, {
40-
...inspectCache,
41-
[target]: typeof action === 'function'
42-
? action(inspectCache[target])
43-
: action
44-
})
45-
}))
46-
export const setHoverAtomFamily = atomFamily(({ path, nestedIndex }) => atom(
47-
(get, set) => set(hoverPathAtom, path
27+
export const getInspectCacheAtom = atom(
28+
(get) => get(inspectCacheAtom),
29+
(get, _set, { path, nestedIndex }) => {
30+
const target = nestedIndex === undefined
31+
? path.join('.')
32+
: `${path.join('.')}[${nestedIndex}]nt`
33+
return get(inspectCacheAtom)[target]
34+
}
35+
)
36+
export const setInspectCacheAtom = atom(
37+
(get) => get(inspectCacheAtom),
38+
(get, set, { path, action, nestedIndex }) => {
39+
const target = nestedIndex === undefined
40+
? path.join('.')
41+
: `${path.join('.')}[${nestedIndex}]nt`
42+
const inspectCache = get(inspectCacheAtom)
43+
return set(inspectCacheAtom, {
44+
...inspectCache,
45+
[target]: typeof action === 'function'
46+
? action(inspectCache[target])
47+
: action
48+
})
49+
}
50+
)
51+
export const setHoverAtom = atom(
52+
(get) => get(hoverPathAtom),
53+
(_get, set, { path, nestedIndex }) => set(hoverPathAtom, path
4854
? { path, nestedIndex }
4955
: null
5056
)
51-
))
52-
export const registryTypesAtomFamily = atomFamily((setState) => atom(
53-
(get, set) => {
57+
)
58+
59+
export const registryTypesAtom = atom(
60+
(get) => get(registryAtom),
61+
(get, set, setState) => {
5462
if (typeof setState === 'function') {
55-
set(registryAtom, setState)
56-
return
63+
return setState(get(registryAtom))
5764
}
58-
return setState
65+
return set(registryAtom, setState)
5966
}
60-
))
67+
)

0 commit comments

Comments
 (0)