Skip to content

Commit ed6c699

Browse files
committed
fix: migrate zustand away from `zustand/context'
1 parent 5bbfcf9 commit ed6c699

File tree

4 files changed

+45
-39
lines changed

4 files changed

+45
-39
lines changed

rollup.config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ const external = [
3030
'@mui/material/styles',
3131
'copy-to-clipboard',
3232
'zustand',
33-
'zustand/context',
3433
'react',
3534
'react/jsx-runtime',
3635
'react-dom',

src/index.tsx

+24-22
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@ import {
33
ThemeProvider
44
} from '@mui/material'
55
import type { FC, ReactElement } from 'react'
6-
import { useCallback, useEffect, useMemo, useRef } from 'react'
6+
import { useCallback, useContext, useEffect, useMemo, useRef } from 'react'
77

88
import { DataKeyPair } from './components/DataKeyPair'
99
import { useThemeDetector } from './hooks/useThemeDetector'
1010
import {
1111
createJsonViewerStore,
12-
JsonViewerProvider,
13-
useJsonViewerStore,
14-
useJsonViewerStoreApi
12+
JsonViewerStoreContext,
13+
useJsonViewerStore
1514
} from './stores/JsonViewerStore'
1615
import {
17-
createTypeRegistryStore, predefined,
18-
TypeRegistryProvider, useTypeRegistryStore
16+
createTypeRegistryStore,
17+
predefined,
18+
TypeRegistryStoreContext,
19+
useTypeRegistryStore
1920
} from './stores/typeRegistry'
2021
import { darkColorspace, lightColorspace } from './theme/base16'
2122
import type { JsonViewerProps } from './type'
@@ -30,21 +31,21 @@ function useSetIfNotUndefinedEffect<Key extends keyof JsonViewerProps> (
3031
key: Key,
3132
value: JsonViewerProps[Key] | undefined
3233
) {
33-
const api = useJsonViewerStoreApi()
34+
const { setState } = useContext(JsonViewerStoreContext)
3435
useEffect(() => {
3536
if (value !== undefined) {
36-
api.setState({
37+
setState({
3738
[key]: value
3839
})
3940
}
40-
}, [key, value, api])
41+
}, [key, value, setState])
4142
}
4243

4344
/**
4445
* @internal
4546
*/
4647
const JsonViewerInner: FC<JsonViewerProps> = (props) => {
47-
const api = useJsonViewerStoreApi()
48+
const { setState } = useContext(JsonViewerStoreContext)
4849
useSetIfNotUndefinedEffect('value', props.value)
4950
useSetIfNotUndefinedEffect('editable', props.editable)
5051
useSetIfNotUndefinedEffect('indentWidth', props.indentWidth)
@@ -60,19 +61,19 @@ const JsonViewerInner: FC<JsonViewerProps> = (props) => {
6061
useSetIfNotUndefinedEffect('onSelect', props.onSelect)
6162
useEffect(() => {
6263
if (props.theme === 'light') {
63-
api.setState({
64+
setState({
6465
colorspace: lightColorspace
6566
})
6667
} else if (props.theme === 'dark') {
67-
api.setState({
68+
setState({
6869
colorspace: darkColorspace
6970
})
7071
} else if (typeof props.theme === 'object') {
71-
api.setState({
72+
setState({
7273
colorspace: props.theme
7374
})
7475
}
75-
}, [api, props.theme])
76+
}, [setState, props.theme])
7677
const onceRef = useRef(true)
7778
const predefinedTypes = useMemo(() => predefined(), [])
7879
const registerTypes = useTypeRegistryStore(store => store.registerTypes)
@@ -143,17 +144,18 @@ export const JsonViewer = function JsonViewer<Value> (props: JsonViewerProps<Val
143144
})
144145
}, [themeType])
145146
const mixedProps = { ...props, theme: themeType }
147+
148+
// eslint-disable-next-line react-hooks/exhaustive-deps
149+
const jsonViewerStore = useMemo(() => createJsonViewerStore(props), [])
150+
const typeRegistryStore = useMemo(() => createTypeRegistryStore(), [])
151+
146152
return (
147153
<ThemeProvider theme={theme}>
148-
<TypeRegistryProvider createStore={createTypeRegistryStore}>
149-
<JsonViewerProvider createStore={() => {
150-
// This function only runs once, so we don't need a memo for this.
151-
// Refs: https://github.com./pmndrs/zustand/blob/77d14b17bc33a6f10f072802fac56aa78510710e/src/context.ts#L36-L38
152-
return createJsonViewerStore(props)
153-
}}>
154+
<TypeRegistryStoreContext.Provider value={typeRegistryStore}>
155+
<JsonViewerStoreContext.Provider value={jsonViewerStore}>
154156
<JsonViewerInner {...mixedProps}/>
155-
</JsonViewerProvider>
156-
</TypeRegistryProvider>
157+
</JsonViewerStoreContext.Provider>
158+
</TypeRegistryStoreContext.Provider>
157159
</ThemeProvider>
158160
)
159161
}

src/stores/JsonViewerStore.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { SetStateAction } from 'react'
2+
import { createContext, useContext } from 'react'
23
import type { StoreApi } from 'zustand'
3-
import { create } from 'zustand'
4-
import createContext from 'zustand/context'
4+
import { create, useStore } from 'zustand'
55

66
import type {
77
JsonViewerOnChange,
@@ -105,8 +105,11 @@ export const createJsonViewerStore = <T = unknown> (props: JsonViewerProps<T>) =
105105
}))
106106
}
107107

108-
export const {
109-
useStore: useJsonViewerStore,
110-
useStoreApi: useJsonViewerStoreApi,
111-
Provider: JsonViewerProvider
112-
} = createContext<StoreApi<JsonViewerState>>()
108+
export const JsonViewerStoreContext = createContext<StoreApi<JsonViewerState>>(undefined)
109+
110+
export const JsonViewerProvider = JsonViewerStoreContext.Provider
111+
112+
export const useJsonViewerStore = <U extends unknown>(selector: (state: JsonViewerState) => U, equalityFn?: (a: U, b: U) => boolean) => {
113+
const store = useContext(JsonViewerStoreContext)
114+
return useStore(store, selector, equalityFn)
115+
}

src/stores/typeRegistry.tsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { Box } from '@mui/material'
22
import type { SetStateAction } from 'react'
3-
import { memo, useMemo, useState } from 'react'
3+
import { createContext, memo, useContext, useMemo, useState } from 'react'
44
import type { StoreApi } from 'zustand'
5-
import { create } from 'zustand'
6-
import createContext from 'zustand/context'
5+
import { createStore, useStore } from 'zustand'
76

87
import { createEasyType } from '../components/DataTypes/createEasyType'
98
import {
@@ -26,7 +25,7 @@ type TypeRegistryState = {
2625
}
2726

2827
export const createTypeRegistryStore = () => {
29-
return create<TypeRegistryState>()((set) => ({
28+
return createStore<TypeRegistryState>()((set) => ({
3029
registry: [],
3130

3231
registerTypes: (setState) => {
@@ -40,11 +39,14 @@ export const createTypeRegistryStore = () => {
4039
}))
4140
}
4241

43-
export const {
44-
Provider: TypeRegistryProvider,
45-
useStore: useTypeRegistryStore,
46-
useStoreApi: useTypeRegistryStoreApi
47-
} = createContext<StoreApi<TypeRegistryState>>()
42+
export const TypeRegistryStoreContext = createContext<StoreApi<TypeRegistryState>>(undefined)
43+
44+
export const TypeRegistryProvider = TypeRegistryStoreContext.Provider
45+
46+
export const useTypeRegistryStore = <U extends unknown>(selector: (state: TypeRegistryState) => U, equalityFn?: (a: U, b: U) => boolean) => {
47+
const store = useContext(TypeRegistryStoreContext)
48+
return useStore(store, selector, equalityFn)
49+
}
4850

4951
const objectType: DataType<object> = {
5052
is: (value) => typeof value === 'object',

0 commit comments

Comments
 (0)