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

fix(readme): description with createWithEqualityFn #1985

Merged
merged 2 commits into from
Aug 12, 2023
Merged

fix(readme): description with createWithEqualityFn #1985

merged 2 commits into from
Aug 12, 2023

Conversation

dai-shi
Copy link
Member

@dai-shi dai-shi commented Aug 9, 2023

Related Issues or Discussions

#1937 (reply in thread)

Summary

Clarify to use createWithEqualityFn for shallow.

Check List

  • yarn run prettier for formatting code and docs

@vercel
Copy link

vercel bot commented Aug 9, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
zustand-demo ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 12, 2023 2:28am

@codesandbox-ci
Copy link

codesandbox-ci bot commented Aug 9, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a757a25:

Sandbox Source
React Configuration
React Typescript Configuration
React Browserify Configuration
React Snowpack Configuration
React Parcel Configuration
Next.js Configuration
@pavlobu/zustand demo Configuration

@github-actions
Copy link

github-actions bot commented Aug 9, 2023

Size Change: 0 B

Total Size: 43.5 kB

ℹ️ View Unchanged
Filename Size
dist/context.js 782 B
dist/esm/context.js 590 B
dist/esm/index.js 706 B
dist/esm/middleware.js 3.87 kB
dist/esm/middleware/immer.js 210 B
dist/esm/shallow.js 509 B
dist/esm/traditional.js 392 B
dist/esm/vanilla.js 629 B
dist/index.js 868 B
dist/middleware.js 4.43 kB
dist/middleware/immer.js 328 B
dist/shallow.js 1.11 kB
dist/system/context.development.js 697 B
dist/system/context.production.js 386 B
dist/system/index.development.js 873 B
dist/system/index.production.js 402 B
dist/system/middleware.development.js 4 kB
dist/system/middleware.production.js 2.62 kB
dist/system/middleware/immer.development.js 292 B
dist/system/middleware/immer.production.js 187 B
dist/system/shallow.development.js 558 B
dist/system/shallow.production.js 344 B
dist/system/traditional.development.js 505 B
dist/system/traditional.production.js 342 B
dist/system/vanilla.development.js 672 B
dist/system/vanilla.production.js 310 B
dist/traditional.js 433 B
dist/umd/context.development.js 887 B
dist/umd/context.production.js 556 B
dist/umd/index.development.js 999 B
dist/umd/index.production.js 543 B
dist/umd/middleware.development.js 4.58 kB
dist/umd/middleware.production.js 2.97 kB
dist/umd/middleware/immer.development.js 482 B
dist/umd/middleware/immer.production.js 342 B
dist/umd/shallow.development.js 1.23 kB
dist/umd/shallow.production.js 883 B
dist/umd/traditional.development.js 613 B
dist/umd/traditional.production.js 447 B
dist/umd/vanilla.development.js 800 B
dist/umd/vanilla.production.js 410 B
dist/vanilla.js 683 B

compressed-size-action

readme.md Outdated
@@ -86,9 +86,22 @@ const honey = useBearStore((state) => state.honey)

If you want to construct a single object with multiple state-picks inside, similar to redux's mapStateToProps, you can tell zustand that you want the object to be diffed shallowly by passing the `shallow` equality function.

To use a custom equality function, you need `createWithEqualityFn` from `zustand/traditional`. It takes the second argument for the default equality function.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel it's a bit confusing — "to use a custom equality function" and then "for the default equality function."

Is the default eq fn a default for that store, but you can still override it later? If so, I suggest:

Suggested change
To use a custom equality function, you need `createWithEqualityFn` from `zustand/traditional`. It takes the second argument for the default equality function.
To use a custom equality function that will become a new default for the store, you need `createWithEqualityFn` from `zustand/traditional`.
Pass an equality function as a second argument.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. Let me clarify and maybe you have some other suggestions.

  • create (in v5) doesn't allow changing equality function. (It's always Object.is equivalent.)
  • To use custom equality function, createWithEqualityFn is necessary.
    • The signature is const useMyStore = createEqualityFn(..., defaultEqualityFn).
    • useMyStore(selector, equalityFn) can override the default equality function.
    • If you specify Object.is for the second argument of createEqualityFn, it behave the same as create < v4.4.0.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Alright, so my proposal:

Suggested change
To use a custom equality function, you need `createWithEqualityFn` from `zustand/traditional`. It takes the second argument for the default equality function.
To use a custom equality function that will become a new default for the store, you need `createWithEqualityFn` from `zustand/traditional`.
Pass a desired equality function as a second argument, like so:

Copy link
Member Author

Choose a reason for hiding this comment

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

What I was concerning is the backward compatibility with previous version. But, I think it's not super important.

Copy link
Member Author

Choose a reason for hiding this comment

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

for the store

It's not for the store (which is still Objet.is), but it's for the hook.

Copy link
Member Author

Choose a reason for hiding this comment

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

"To use a custom equality function, you need createWithEqualityFn instead of create. Usually, specify Object.is at the second argument for the default equality function, but it's configurable." How about that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

"To use a custom equality function, you need createWithEqualityFn instead of create. Usually you want to specify Object.is as the second argument for the default equality function, but it's configurable."

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I'll update it later.

increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
}),
Object.is // Specify the default equality function, which can be shallow
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the eq fn is shallow, what is the effect of using 'zustand/shallow'? Isn't the eq fn always shallow then, regardless of it?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you do this:

import { createWithEqualityFn } from 'zustand/traditional'
import { shallow } from 'zustand/shallow'

const useMyStore = createWithEqualityFn(..., shallow)

You don't need to specify shallow for useMyStore:

  useMyStore(...)
  // that 👆 is the same as this 👇 
  useMyStore(..., shallow)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Object.is // Specify the default equality function, which can be shallow
customEqualityFunction // This will become the default equality function, unless you pass another one to `useBearStore` hook.

And then I'd add a customEqualityFunction.

Copy link
Member Author

Choose a reason for hiding this comment

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

customEqualityFunction is not defined anywhere, so I think it's confusing.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought about defining it, but you said that readme should be minimal, and I agree, so I don't push that hard on this.

Copy link
Collaborator

@sewera sewera left a comment

Choose a reason for hiding this comment

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

I'd explicitly write some example of an actually different equality function than the Object.is to highlight the use case.

One use case I can think about that better highlights what a real-world scenario could be would be something like:

const useNotificationStore = createWithEqualityFn(set => ({
    notifications: []
    addNotification: notification => set(state => ({ notifications: [...state.notifications, notification] }))
  }),
  hashEquality
)

function hashEquality(a, b) {
  return JSON.stringify(a.notifications.map(it => it.hash)) === JSON.stringify(b.notifications.map(it => it.hash))
}

provided that notification hash is computed in backend.

readme.md Outdated
@@ -86,9 +86,22 @@ const honey = useBearStore((state) => state.honey)

If you want to construct a single object with multiple state-picks inside, similar to redux's mapStateToProps, you can tell zustand that you want the object to be diffed shallowly by passing the `shallow` equality function.

To use a custom equality function, you need `createWithEqualityFn` from `zustand/traditional`. It takes the second argument for the default equality function.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Alright, so my proposal:

Suggested change
To use a custom equality function, you need `createWithEqualityFn` from `zustand/traditional`. It takes the second argument for the default equality function.
To use a custom equality function that will become a new default for the store, you need `createWithEqualityFn` from `zustand/traditional`.
Pass a desired equality function as a second argument, like so:

increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
}),
Object.is // Specify the default equality function, which can be shallow
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Object.is // Specify the default equality function, which can be shallow
customEqualityFunction // This will become the default equality function, unless you pass another one to `useBearStore` hook.

And then I'd add a customEqualityFunction.

```jsx
import { createWithEqualityFn } from 'zustand/traditional'
import { shallow } from 'zustand/shallow'

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const customEqualityFunction = (a, b) => a.bears === b.bears

@dai-shi
Copy link
Member Author

dai-shi commented Aug 9, 2023

I'd explicitly write some example

That would be good, but our strong desire is to keep readme.md as minimal as possible.
So, what I'd like to do is to show something very essential in readme.md and link to docs for details.
See: https://github.com/pmndrs/zustand#typescript-usage

@sewera
Copy link
Collaborator

sewera commented Aug 9, 2023

You're right. I still suggest this rephrasal: #1985 (comment)

@dai-shi dai-shi merged commit 49d43b7 into main Aug 12, 2023
@dai-shi dai-shi deleted the fix/readme branch August 12, 2023 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants