Skip to content

Commit

Permalink
feat: deprecate some APIs toward v5 (pmndrs#1403)
Browse files Browse the repository at this point in the history
* feat: deprecate some APIs toward v5

* update docs
  • Loading branch information
dai-shi authored Jan 10, 2023
1 parent 86c5016 commit 7d32f9c
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/previous-versions/zustand-v3-create-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ nav: 18
A special `createContext` is provided since v3.5,
which avoids misusing the store hook.

> **Note**: This function will likely be deprecated in v4 and removed in v5.
> **Note**: This function will be deprecated in v4 and removed in v5.
```jsx
import create from 'zustand'
Expand Down
18 changes: 8 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ const unsub1 = useDogStore.subscribe(console.log)
useDogStore.setState({ paw: false })
// Unsubscribe listeners
unsub1()
// Destroying the store (removing all listeners)
useDogStore.destroy()

// You can of course use the hook as you always would
const Component = () => {
Expand Down Expand Up @@ -222,19 +220,21 @@ const unsub5 = useDogStore.subscribe((state) => state.paw, console.log, {
Zustand core can be imported and used without the React dependency. The only difference is that the create function does not return a hook, but the API utilities.
```jsx
import create from 'zustand/vanilla'
import createStore from 'zustand/vanilla'

const store = create(() => ({ ... }))
const { getState, setState, subscribe, destroy } = store
const store = createStore(() => ({ ... }))
const { getState, setState, subscribe } = store

export default store
```
You can even consume an existing vanilla store with React:
You can use a vanilla store with `useStore` hook available since v4.
```jsx
import create from 'zustand'
import { useStore } from 'zustand'
import vanillaStore from './vanillaStore'

const useBoundStore = create(vanillaStore)
const useBoundStore = (selector) => useStore(vanillaStore, selector)
```
:warning: Note that middlewares that modify `set` or `get` are not applied to `getState` and `setState`.
Expand Down Expand Up @@ -477,8 +477,6 @@ const Component = () => {
...
```
[Alternatively, a special createContext is provided.](./docs/previous-versions/zustand-v3-create-context.md)
## TypeScript Usage
Basic typescript usage doesn't require anything special except for writing `create<State>()(...)` instead of `create(...)`...
Expand Down
8 changes: 8 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ type ExtractState<S> = S extends { getState: () => infer T } ? T : never

type WithoutCallSignature<T> = { [K in keyof T]: T[K] }

/**
* @deprecated Use `createStore` and `useStore` for context usage
*/
function createContext<S extends StoreApi<unknown>>() {
if (__DEV__) {
console.warn(
'[DEPRECATED] zustand/context will be removed in the future version. Please use `import { createStore, useStore } from "zustand"` for context usage. See: https://github.com/pmndrs/zustand/discussions/1180'
)
}
const ZustandContext = reactCreateContext<S | undefined>(undefined)

const Provider = ({
Expand Down
8 changes: 8 additions & 0 deletions src/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,18 @@ type Create = {
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(
initializer: StateCreator<T, [], Mos>
) => UseBoundStore<Mutate<StoreApi<T>, Mos>>
/**
* @deprecated Use `useStore` hook to bind store
*/
<S extends StoreApi<unknown>>(store: S): UseBoundStore<S>
}

const createImpl = <T>(createState: StateCreator<T, [], []>) => {
if (__DEV__ && typeof createState !== 'function') {
console.warn(
'[DEPRECATED] Passing a vanilla store will be unsupported in the future version. Please use `import { useStore } from "zustand"` to use the vanilla store in React.'
)
}
const api =
typeof createState === 'function' ? createStore(createState) : createState

Expand Down
13 changes: 12 additions & 1 deletion src/vanilla.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export interface StoreApi<T> {
setState: SetStateInternal<T>
getState: () => T
subscribe: (listener: (state: T, prevState: T) => void) => () => void
/**
* @deprecated Use `unsubscribe` returned by `subscribe`
*/
destroy: () => void
}

Expand Down Expand Up @@ -85,7 +88,15 @@ const createStoreImpl: CreateStoreImpl = (createState) => {
return () => listeners.delete(listener)
}

const destroy: StoreApi<TState>['destroy'] = () => listeners.clear()
const destroy: StoreApi<TState>['destroy'] = () => {
if (__DEV__) {
console.warn(
'[DEPRECATED] The destroy method will be unsupported in the future version. You should use unsubscribe function returned by subscribe. Everything will be garbage collected if store is garbage collected.'
)
}
listeners.clear()
}

const api = { setState, getState, subscribe, destroy }
state = createState(setState, getState, api)
return api as any
Expand Down

0 comments on commit 7d32f9c

Please sign in to comment.