Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: deprecate some APIs toward v5 #1403

Merged
merged 4 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that this will require more TS boilerplate

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's just a little. Such usage is already documented somewhere. If people use this pattern a lot, we could provide a util for it. Thanks for your feedback!

```

:warning: Note that middlewares that modify `set` or `get` are not applied to `getState` and `setState`.
Expand Down Expand Up @@ -462,8 +462,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: () => void = () => listeners.clear()
const destroy: () => void = () => {
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