Skip to content

Commit

Permalink
fix(docs): useBoundStore instead of useStore (pmndrs#1125)
Browse files Browse the repository at this point in the history
* fix(docs): useBoundStore instead of useStore

* run prettier
  • Loading branch information
dai-shi authored Jul 25, 2022
1 parent f07276c commit fa581dd
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 410 deletions.
8 changes: 4 additions & 4 deletions docs/auto-generating-selectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ interface BearState {
increment: () => void
}

const useStoreBase = create<BearState>()((set) => ({
const useBearStoreBase = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
increment: () => set((state) => ({ bears: state.bears + 1 })),
Expand All @@ -49,17 +49,17 @@ const useStoreBase = create<BearState>()((set) => ({
## Apply that function to your store:

```typescript
const useStore = createSelectors(useStoreBase)
const useBearStore = createSelectors(useBearStoreBase)
```

## Now the selectors are auto generated:

```typescript
// get the property
const bears = useStore.use.bears()
const bears = useBearStore.use.bears()

// get the action
const increase = useStore.use.increment()
const increase = useBearStore.use.increment()
```

## Live Demo
Expand Down
4 changes: 2 additions & 2 deletions docs/event-handler-in-pre-react-18.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ In order to fix this, the action needs to be wrapped in `unstable_batchedUpdates
```jsx
import { unstable_batchedUpdates } from 'react-dom' // or 'react-native'

const useStore = create((set) => ({
const useFishStore = create((set) => ({
fishes: 0,
increaseFishes: () => set((prev) => ({ fishes: prev.fishes + 1 })),
}))

const nonReactCallback = () => {
unstable_batchedUpdates(() => {
useStore.getState().increaseFishes()
useFishStore.getState().increaseFishes()
})
}
```
Expand Down
8 changes: 4 additions & 4 deletions docs/flux-inspired-practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Although zustand is an unopinionated library, here's one of the recommended usag
- Define dispatch functions at the root level of the store to update one or more store slices

```js
const useStore = create((set) => ({
const useBoundStore = create((set) => ({
storeSliceA: ...,
storeSliceB: ...,
storeSliceC: ...,
Expand All @@ -34,12 +34,12 @@ const reducer = (state, { type, by = 1 }) => {
}
}

const useStore = create((set) => ({
const useGrumpyStore = create((set) => ({
grumpiness: 0,
dispatch: (args) => set((state) => reducer(state, args)),
}))

const dispatch = useStore((state) => state.dispatch)
const dispatch = useGrumpyStore((state) => state.dispatch)
dispatch({ type: types.increase, by: 2 })
```

Expand All @@ -48,7 +48,7 @@ Or, just use our redux-middleware. It wires up your main-reducer, sets initial s
```typescript
import { redux } from 'zustand/middleware'

const useStore = create(redux(reducer, initialState))
const useReduxStore = create(redux(reducer, initialState))
```

Another way to update the store could be in functions wrapping the state functions. These could also handle side-effects of actions, for example for HTTP-calls. For using Zustand in a none-reactive way see [the readme](https://github.com/pmndrs/zustand#readingwriting-state-and-reacting-to-changes-outside-of-components)
56 changes: 28 additions & 28 deletions docs/persisting-store-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Quick example:
import create from 'zustand'
import { persist } from 'zustand/middleware'

export const useStore = create(
export const useFishStore = create(
persist(
(set, get) => ({
fishes: 0,
Expand Down Expand Up @@ -44,7 +44,7 @@ Simply pass a function that returns the storage you want to use.
Example:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
// ...
Expand Down Expand Up @@ -78,7 +78,7 @@ Since the only way to store an object in a storage is via a string, you can use
For example, if you want to store your state in base64:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
// ...
Expand All @@ -104,7 +104,7 @@ If you pass a custom serialize function, you will most likely need to pass a cus
To continue the example above, you could deserialize the base64 value using the following:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
// ...
Expand All @@ -128,7 +128,7 @@ Enables you to omit some of the state's fields to be stored in the storage.
You could omit multiple fields using the following:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
foo: 0,
Expand All @@ -148,7 +148,7 @@ export const useStore = create(
Or you could allow only specific fields using the following:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
foo: 0,
Expand All @@ -171,7 +171,7 @@ This option enables you to pass a listener function that will be called when the
Example:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
// ...
Expand Down Expand Up @@ -218,7 +218,7 @@ The migrate function takes the persisted state and the version number as argumen
For instance, if you want to rename a field, you can use the following:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
newField: 0, // let's say this field was named otherwise in version 0
Expand Down Expand Up @@ -275,7 +275,7 @@ The shallow merge will erase the `baz` field from the `foo` object.
One way to fix this would be to give a custom deep merge function:

```ts
export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
foo: {
Expand Down Expand Up @@ -307,7 +307,7 @@ This method can you get the options of the middleware.
For example, it can be used to obtain the storage name:

```ts
useStore.persist.getOptions().name
useBoundStore.persist.getOptions().name
```

### `setOptions`
Expand All @@ -319,15 +319,15 @@ This method enables you to change the middleware options. Note that the new opti
For instance, this can be used to change the storage name:

```ts
useStore.persist.setOptions({
useBoundStore.persist.setOptions({
name: 'new-name',
})
```

Or even to change the storage engine:

```ts
useStore.persist.setOptions({
useBoundStore.persist.setOptions({
getStorage: () => sessionStorage,
})
```
Expand All @@ -339,7 +339,7 @@ useStore.persist.setOptions({
This can be used to fully clear the persisted value in the storage.

```ts
useStore.persist.clearStorage()
useBoundStore.persist.clearStorage()
```

### `rehydrate`
Expand All @@ -350,17 +350,17 @@ In some cases, you might want to trigger a rehydration manually.
This can be done by calling the `rehydrate` method.

```ts
await useStore.persist.rehydrate()
await useBoundStore.persist.rehydrate()
```

### `hasHydrated`

> Schema: `() => boolean`
This is a non-reactive getter to know if the storage has been hydrated (note that this does update when calling `useStore.persist.rehydrate()`).
This is a non-reactive getter to know if the storage has been hydrated (note that this does update when calling `useBoundStore.persist.rehydrate()`).

```ts
useStore.persist.hasHydrated()
useBoundStore.persist.hasHydrated()
```

### `onHydrate`
Expand All @@ -370,7 +370,7 @@ useStore.persist.hasHydrated()
The given listener will be called when the hydration process starts.

```ts
const unsub = useStore.persist.onHydrate((state) => {
const unsub = useBoundStore.persist.onHydrate((state) => {
console.log('hydration starts')
})

Expand All @@ -385,7 +385,7 @@ unsub()
The given listener will be called when the hydration process ends.

```ts
const unsub = useStore.persist.onFinishHydration((state) => {
const unsub = useBoundStore.persist.onFinishHydration((state) => {
console.log('hydration finished')
})

Expand Down Expand Up @@ -420,7 +420,7 @@ There's a fiew different ways to do this.
You can use the `onRehydrateStorage` option to update a field in the store:

```ts
const useStore = create(
const useBoundStore = create(
persist(
(set, get) => ({
// ...
Expand All @@ -441,7 +441,7 @@ const useStore = create(
);

export default function App() {
const hasHydrated = useStore(state => state._hasHydrated);
const hasHydrated = useBoundStore(state => state._hasHydrated);

if (!hasHydrated) {
return <p>Loading...</p>
Expand All @@ -456,16 +456,16 @@ export default function App() {
You can also create a custom `useHydration` hook:

```ts
const useStore = create(persist(...))
const useBoundStore = create(persist(...))

const useHydration = () => {
const [hydrated, setHydrated] = useState(useStore.persist.hasHydrated)
const [hydrated, setHydrated] = useState(useBoundStore.persist.hasHydrated)

useEffect(() => {
const unsubHydrate = useStore.persist.onHydrate(() => setHydrated(false)) // Note: this is just in case you want to take into account manual rehydrations. You can remove this if you don't need it/don't want it.
const unsubFinishHydration = useStore.persist.onFinishHydration(() => setHydrated(true))
const unsubHydrate = useBoundStore.persist.onHydrate(() => setHydrated(false)) // Note: this is just in case you want to take into account manual rehydrations. You can remove this if you don't need it/don't want it.
const unsubFinishHydration = useBoundStore.persist.onFinishHydration(() => setHydrated(true))

setHydrated(useStore.persist.hasHydrated())
setHydrated(useBoundStore.persist.hasHydrated())

return () => {
unsubHydrate()
Expand Down Expand Up @@ -502,7 +502,7 @@ const storage: StateStorage = {
},
}

export const useStore = create(
export const useBoundStore = create(
persist(
(set, get) => ({
fishes: 0,
Expand Down Expand Up @@ -538,6 +538,6 @@ export const withStorageDOMEvents = (store: StoreWithPersist) => {
}
}

const useStore = create(persist(...))
withStorageDOMEvents(useStore)
const useBoundStore = create(persist(...))
withStorageDOMEvents(useBoundStore)
```
28 changes: 14 additions & 14 deletions docs/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface BearState {
increase: (by: number) => void
}

const useStore = create<BearState>()((set) => ({
const useBearStore = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}))
Expand Down Expand Up @@ -59,7 +59,7 @@ The thing is Zustand is lying in it's type, the simplest way to prove it by show
```ts
import create from 'zustand/vanilla'

const useStore = create<{ foo: number }>()((_, get) => ({
const useBoundStore = create<{ foo: number }>()((_, get) => ({
foo: get().foo,
}))
```
Expand Down Expand Up @@ -121,7 +121,7 @@ Alternatively you can also use `combine` which infers the state instead of you h
import create from 'zustand'
import { combine } from 'zustand/middleware'

const useStore = create(
const useBearStore = create(
combine({ bears: 0 }, (set) => ({
increase: (by: number) => set((state) => ({ bears: state.bears + by })),
}))
Expand All @@ -133,9 +133,9 @@ const useStore = create(

<br/>

We achieve the inference by lying a little in the types of `set`, `get` and `store` that you receive as parameters. The lie is that they're typed in a way as if the state is the first parameter only when in fact the state is the shallow-merge (`{ ...a, ...b }`) of both first parameter and the second parameter's return. So for example `get` from the second parameter has type `() => { bears: number }` and that's a lie as it should be `() => { bears: number, increase: (by: number) => void }`. And `useStore` still has the correct type, ie for example `useStore.getState` is typed as `() => { bears: number, increase: (by: number) => void }`.
We achieve the inference by lying a little in the types of `set`, `get` and `store` that you receive as parameters. The lie is that they're typed in a way as if the state is the first parameter only when in fact the state is the shallow-merge (`{ ...a, ...b }`) of both first parameter and the second parameter's return. So for example `get` from the second parameter has type `() => { bears: number }` and that's a lie as it should be `() => { bears: number, increase: (by: number) => void }`. And `useBoundStore` still has the correct type, ie for example `useBoundStore.getState` is typed as `() => { bears: number, increase: (by: number) => void }`.

It's not a lie lie because `{ bears: number }` is still a subtype `{ bears: number, increase: (by: number) => void }`, so in most cases there won't be a problem. Just you have to be careful while using replace. For eg `set({ bears: 0 }, true)` would compile but will be unsound as it'll delete the `increase` function. (If you set from "outside" ie `useStore.setState({ bears: 0 }, true)` then it won't compile because the "outside" store knows that `increase` is missing.) Another instance where you should be careful you're doing `Object.keys`, `Object.keys(get())` will return `["bears", "increase"]` and not `["bears"]` (the return type of `get` can make you fall for this).
It's not a lie lie because `{ bears: number }` is still a subtype `{ bears: number, increase: (by: number) => void }`, so in most cases there won't be a problem. Just you have to be careful while using replace. For eg `set({ bears: 0 }, true)` would compile but will be unsound as it'll delete the `increase` function. (If you set from "outside" ie `useBoundStore.setState({ bears: 0 }, true)` then it won't compile because the "outside" store knows that `increase` is missing.) Another instance where you should be careful you're doing `Object.keys`, `Object.keys(get())` will return `["bears", "increase"]` and not `["bears"]` (the return type of `get` can make you fall for this).

So `combine` trades-off a little type-safety for the convenience of not having to write a type for state. Hence you should use `combine` accordingly, usually it's not a big deal and it's okay to use it.

Expand All @@ -156,7 +156,7 @@ interface BearState {
increase: (by: number) => void
}

const useStore = create<BearState>()(
const useBearStore = create<BearState>()(
devtools(
persist((set) => ({
bears: 0,
Expand All @@ -179,7 +179,7 @@ interface BearState {
increase: (by: number) => void
}

const useStore = create<BearState>()(
const useBearStore = create<BearState>()(
myMiddlewares((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
Expand All @@ -199,8 +199,8 @@ const foo = (f, bar) => (set, get, store) => {
return f(set, get, store)
}

const useStore = create(foo(() => ({ bears: 0 }), 'hello'))
console.log(useStore.foo.toUpperCase())
const useBearStore = create(foo(() => ({ bears: 0 }), 'hello'))
console.log(useBearStore.foo.toUpperCase())
```

Yes, if you didn't know Zustand middlewares do and are allowed to mutate the store. But how could we possibly encode the mutation on the type-level? That is to say how could do we type `foo` so that this code compiles?
Expand Down Expand Up @@ -251,7 +251,7 @@ type PopArgument<T extends (...a: never[]) => unknown> = T extends (

// ---

const useStore = create<BearState>()(
const useBearStore = create<BearState>()(
logger(
(set) => ({
bears: 0,
Expand Down Expand Up @@ -317,8 +317,8 @@ type Cast<T, U> = T extends U ? T : U

// ---

const useStore = create(foo(() => ({ bears: 0 }), 'hello'))
console.log(useStore.foo.toUpperCase())
const useBearStore = create(foo(() => ({ bears: 0 }), 'hello'))
console.log(useBearStore.foo.toUpperCase())
```

### `create` without curried workaround
Expand All @@ -333,7 +333,7 @@ interface BearState {
increase: (by: number) => void
}

const useStore = create<
const useBearStore = create<
BearState,
[
['zustand/persist', BearState],
Expand Down Expand Up @@ -380,7 +380,7 @@ const createFishSlice: StateCreator<
addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
})

const useStore = create<BearSlice & FishSlice>()((...a) => ({
const useBoundStore = create<BearSlice & FishSlice>()((...a) => ({
...createBearSlice(...a),
...createFishSlice(...a),
}))
Expand Down
Loading

0 comments on commit fa581dd

Please sign in to comment.