Skip to content

fix(docs): Issue 1120 docs #1231

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

Merged
merged 11 commits into from
Aug 29, 2022
12 changes: 6 additions & 6 deletions docs/guides/auto-generating-selectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ title: Auto Generating Selectors
nav: 7
---

It is recommended to use selectors when using either the properties or actions from the store.
We recommend using selectors when using either the properties or actions from the store. You can access values from the store like so:

```typescript
const bears = useBearStore((state) => state.bears)
```

However, writing these could be tedious, but you can auto-generate them
However, writing these could be tedious. If that is the case for you, you can auto-generate your selectors.

## create the following function: `createSelectors`

Expand All @@ -33,7 +33,7 @@ const createSelectors = <S extends UseBoundStore<StoreApi<State>>>(
}
```

## If you have a store like this:
If you have a store like this:

```typescript
interface BearState {
Expand All @@ -49,13 +49,13 @@ const useBearStoreBase = create<BearState>()((set) => ({
}))
```

## Apply that function to your store:
Apply that function to your store:

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

## Now the selectors are auto generated:
Now the selectors are auto generated and you can access them directly:

```typescript
// get the property
Expand All @@ -67,7 +67,7 @@ const increase = useBearStore.use.increment()

## Live Demo

for a working example of this, see the [Code Sandbox](https://codesandbox.io/s/zustand-auto-generate-selectors-9i0ob3?file=/src/store.ts:396-408)
For a working example of this, see the [Code Sandbox](https://codesandbox.io/s/zustand-auto-generate-selectors-9i0ob3?file=/src/store.ts:396-408).

## 3rd-party Libraries

Expand Down
4 changes: 2 additions & 2 deletions docs/guides/event-handler-in-pre-react-18.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ title: Calling actions outside a React event handler in pre React 18
nav: 11
---

Because React handles `setState` synchronously if it's called outside an event handler. Updating the state outside an event handler will force react to update the components synchronously, therefore adding the risk of encountering the zombie-child effect.
In order to fix this, the action needs to be wrapped in `unstable_batchedUpdates`
Because React handles `setState` synchronously if it's called outside an event handler, updating the state outside an event handler will force react to update the components synchronously. Therefore, there is a risk of encountering the zombie-child effect.
In order to fix this, the action needs to be wrapped in `unstable_batchedUpdates` like so:

```jsx
import { unstable_batchedUpdates } from 'react-dom' // or 'react-native'
Expand Down
18 changes: 9 additions & 9 deletions docs/guides/flux-inspired-practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ title: Flux inspired practice
nav: 6
---

Although zustand is an unopinionated library, here's one of the recommended usages:
Although zustand is an unopinionated library, here are some patterns we recommend:

- Create one single store
- Define a store only with `set`
- Define dispatch functions at the root level of the store to update one or more store slices
- Create a single store;
- Always use `set` to define a store;
- Define your dispatch functions at the root level of the store to update one or more store slices.

```js
const useBoundStore = create((set) => ({
Expand All @@ -19,11 +19,11 @@ const useBoundStore = create((set) => ({
}))
```

See [Splitting the store into separate slices](https://github.com/pmndrs/zustand/blob/main/docs/typescript.md#slices-pattern) for how to define a store with separate slices.
See [Splitting the store into separate slices](https://github.com/pmndrs/zustand/blob/main/docs/guides/typescript.md#slices-pattern) for how to define a store with separate slices.
Copy link
Collaborator

Choose a reason for hiding this comment

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

[no action] This highlights a "post launch" action. Once the docs are all squared away, we may need to do a pass and update the links to point to the docs themselves rather than back to the repo.

Copy link
Member

@dai-shi dai-shi Aug 28, 2022

Choose a reason for hiding this comment

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

@chrisk-7777 We want to make it work to view docs in github. I believe relative paths should work.

Suggested change
See [Splitting the store into separate slices](https://github.com/pmndrs/zustand/blob/main/docs/guides/typescript.md#slices-pattern) for how to define a store with separate slices.
See [Splitting the store into separate slices](./typescript.md#slices-pattern) for how to define a store with separate slices.


## Flux like patterns / "Dispatching" actions
## Flux like patterns / "dispatching" actions

If you can't live without redux-like reducers, you can define a `dispatch` function on the root level of the store like store
If you can't live without redux-like reducers, you can define a `dispatch` function on the root level of the store like so:

```typescript
const types = { increase: 'INCREASE', decrease: 'DECREASE' }
Expand All @@ -46,12 +46,12 @@ const dispatch = useGrumpyStore((state) => state.dispatch)
dispatch({ type: types.increase, by: 2 })
```

Or, just use our redux-middleware. It wires up your main-reducer, sets initial state, and adds a dispatch function to the state itself and the vanilla api. Try [this](https://codesandbox.io/s/amazing-kepler-swxol) example.
You could also use our redux-middleware. It wires up your main reducer, sets initial state, and adds a dispatch function to the state itself and the vanilla api. Check [this example](https://codesandbox.io/s/amazing-kepler-swxol).
Copy link
Collaborator

Choose a reason for hiding this comment

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

[no action] Small thing, but these longer links are great for accessibility I believe ("this example" vs previous "this") 👍


```typescript
import { redux } from 'zustand/middleware'

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)
Another way to update the store could be through functions wrapping the state functions. These could also handle side-effects of actions. For example, with HTTP-calls. To use Zustand in a none-reactive way, see [the readme](https://github.com/pmndrs/zustand#readingwriting-state-and-reacting-to-changes-outside-of-components).
22 changes: 11 additions & 11 deletions docs/guides/immutable-state-and-merging.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ title: Immutable state and merging
nav: 5
---

Like `useState`, we need to update state immutably.
Like with React's `useState`, we need to update state immutably.

Here's a typical example.
Here's a typical example:

```jsx
import create from 'zustand'
Expand All @@ -16,24 +16,24 @@ const useCountStore = create((set) => ({
}))
```

The `set` function is to update state in store.
Because the state is immutable, it should have been this:
The `set` function is to update state in the store.
Because the state is immutable, it should have been like this:

```js
set((state) => ({ ...state, count: state.count + 1 }))
```

As this happens very often, `set` actually merges state, and
we can skip `...state` part:
However, as this is a common pattern, `set` actually merges state, and
we can skip the `...state` part:

```js
set((state) => ({ count: state.count + 1 }))
```

## Nested objects

The `set` function merges state only one level.
If you have a nested object, you need to merge them explicitly.
The `set` function merges state at only one level.
If you have a nested object, you need to merge them explicitly. You will use the spread operator pattern like so:

```jsx
import create from 'zustand'
Expand All @@ -47,12 +47,12 @@ const useCountStore = create((set) => ({
}))
```

For complex use cases, consider using some libraries that helps immutable updates.
Refer [Updating nested state object values](./updating-nested-state-object-values.md).
For complex use cases, consider using some libraries that help with immutable updates.
You can refer to [Updating nested state object values](./updating-nested-state-object-values.md).

## Replace flag

To disable the merging behavior, you can specify `replace` boolean value to `set`.
To disable the merging behavior, you can specify a `replace` boolean value for `set` like so:

```js
set((state) => newState, true)
Expand Down
8 changes: 4 additions & 4 deletions docs/guides/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ nav: 10

When running tests, the stores are not automatically reset before each test run.

Thus, there can be cases where the state of one test can affect another. To make sure all tests run with a pristine store state, you can mock `zustand` during testing and replace it with the following code:
Thus, there can be cases where the state of one test can affect another. To make sure all tests run with a pristine store state, you can mock `zustand` during testing and use the following code to create your store:

```jsx
import actualCreate from 'zustand'
Expand All @@ -34,13 +34,13 @@ beforeEach(() => {
export default create
```

The way you can mock a dependency depends on your test runner.
The way you mock a dependency depends on your test runner/library.

In [jest](https://jestjs.io/), you can create a `__mocks__/zustand.js` and place the code there. If your app is using `zustand/vanilla` instead of `zustand`, then you'll have to place the above code in `__mocks__/zustand/vanilla.js`.
In [jest](https://jestjs.io/), you can create a `__mocks__/zustand.js` and place the code in that file. If your app is using `zustand/vanilla` instead of `zustand`, then you'll have to place the above code in `__mocks__/zustand/vanilla.js`.

## Resetting state between tests in **react-native** and **jest**

in the `__mocks__/zustand.js` (the `__mocks__` directory should be adjacent to node_modules, unless you configured roots to point to a folder other than the project root [jest docs: mocking node modules](https://jestjs.io/docs/manual-mocks#mocking-node-modules)):
You should use the following code in the `__mocks__/zustand.js` file (the `__mocks__` directory should be adjacent to node_modules, placed in the same folder as node_modules, unless you configured roots to point to a folder other than the project root [jest docs: mocking node modules](https://jestjs.io/docs/manual-mocks#mocking-node-modules)):

```js
import { act } from '@testing-library/react-native'
Expand Down