@90pixel/zustand.macro 中文文档教程

发布于 3年前 浏览 22 项目主页 更新于 3年前

zustand.macro

babel-macro npm npm NPM

Getting Started

此软件包旨在改善使用 zustand 管理 React 应用程序中的状态时的开发人员体验 (DX)

Table of Contents


The Problem

假设我们有一家这样的商店;

import create from "zustand";

const useStore = create((set) => ({
    count: 0,
    incrementCount: () => set((state) => ({ count: state.count + 1 })),
    decrementCount: () => set((state) => ({ count: state.count - 1 })),
}));

如果我们这样使用这家商店;

export default function CounterA() {
    const { count } = usestore();
    // ...
}

我们会遇到重新渲染的问题。 组件将在存储中的任何属性更改时重新呈现。

我们需要像这样使用商店,以避免重新渲染问题。

export default function CounterA() {
    const count = useStore((state) => state.count);
    // ...
}

What if we need more than one prop?

现在我们需要使用具有浅层相等功能的商店。

import shallow from "zustand/shallow";

export default function CounterA() {
    const { count, incrementCount, decrementCount } = useStore(
        (s) => ({
            count: s.count,
            incrementCount: s.incrementCount,
            decrementCount: s.decrementCount,
        }),
        shallow
    );
    // ...
}

我们重复了很多。

Solution

使用 babel-plugin-macros 我们可以在 compile-time 将这段代码变成下面的代码。

import useStoreMacro from "@90pixel/zustand.macro";

const {
  count,
  decrementCount,
  incrementCount,
} = useStoreMacro();

      ↓ ↓ ↓ ↓ ↓ ↓

// You can replace this with your own hook. Look at the Configuration section to learn more about it.
import { useShallowStore as _useShallowStore } from "hooks";

const {
  count,
  decrementCount,
  incrementCount,
} = _useShallowStore((s) => ({
  count: s.count,
  decrementCount: s.decrementCount,
  incrementCount: s.incrementCount,
}));

Installation

安装依赖项。

npm install --save-dev @90pixel/zustand.macro babel-plugin-macros

或者使用 yarn

yarn add -D @90pixel/zustand.macro babel-plugin-macros

Updating Your Babel config

你必须将 babel-plugin-macros 插件添加到你的 babel 插件列表中。

{
  // ...
  "plugins": [
    // ...other plugins

    // This must be added
    "macros"
  ]
}

Adding useShallowStore hook

将此挂钩添加到您的自定义挂钩中。

import shallow from "zustand/shallow";
// Your store..
import { useStore } from "store";

export default function useShallowStore(selector, equalityFn = shallow) {
    return useStore(selector, equalityFn);
}

Configuration

默认情况下,当您导入宏时,导入语句将在编译时删除。

将添加浅存储实现。

import useStoreMacro from "@90pixel/zustand.macro";
      ↓ ↓ ↓ ↓ ↓ ↓
import { useShallowStore as _useShallowStore } from "hooks";

如您所见,导入名称 (useShallowStore) 和导入源 (import .. from 'hooks') 是硬编码的。

您可以在 package.json 文件中更改这些。

{
  ...
  "babelMacros": {

    "zustandMacro": {
      "useStore": {
        "importName": "useShallowStore",
        "importSource": "hooks"
      }
    }
  }
}

您现在可以开始了。

zustand.macro

babel-macro npm npm NPM

Getting Started

This package is designed to improve the Developer Experience (DX) when working with zustand to manage the state in React applications.

Table of Contents


The Problem

Lets say we have a store like this;

import create from "zustand";

const useStore = create((set) => ({
    count: 0,
    incrementCount: () => set((state) => ({ count: state.count + 1 })),
    decrementCount: () => set((state) => ({ count: state.count - 1 })),
}));

If we use this store like this;

export default function CounterA() {
    const { count } = usestore();
    // ...
}

We will encounter re-rendering issues. The <CounterA /> component will re-render when any of the properties changed in store.

We will need to use the store like this, to avoid re-rendering issues.

export default function CounterA() {
    const count = useStore((state) => state.count);
    // ...
}

What if we need more than one prop?

Now we need to use the store with shallow equality function.

import shallow from "zustand/shallow";

export default function CounterA() {
    const { count, incrementCount, decrementCount } = useStore(
        (s) => ({
            count: s.count,
            incrementCount: s.incrementCount,
            decrementCount: s.decrementCount,
        }),
        shallow
    );
    // ...
}

We are repeating a lot.

Solution

Using babel-plugin-macros we can turn this code into this below, at compile-time.

import useStoreMacro from "@90pixel/zustand.macro";

const {
  count,
  decrementCount,
  incrementCount,
} = useStoreMacro();

      ↓ ↓ ↓ ↓ ↓ ↓

// You can replace this with your own hook. Look at the Configuration section to learn more about it.
import { useShallowStore as _useShallowStore } from "hooks";

const {
  count,
  decrementCount,
  incrementCount,
} = _useShallowStore((s) => ({
  count: s.count,
  decrementCount: s.decrementCount,
  incrementCount: s.incrementCount,
}));

Installation

Installation of the dependencies.

npm install --save-dev @90pixel/zustand.macro babel-plugin-macros

or using yarn

yarn add -D @90pixel/zustand.macro babel-plugin-macros

Updating Your Babel config

You must add the babel-plugin-macros plugin into your babel plugin list.

{
  // ...
  "plugins": [
    // ...other plugins

    // This must be added
    "macros"
  ]
}

Adding useShallowStore hook

Add this hook into your custom hooks.

import shallow from "zustand/shallow";
// Your store..
import { useStore } from "store";

export default function useShallowStore(selector, equalityFn = shallow) {
    return useStore(selector, equalityFn);
}

Configuration

By default when you import the macro, the import statement will be deleted at compile-time.

Shallow store implementation will be added instead.

import useStoreMacro from "@90pixel/zustand.macro";
      ↓ ↓ ↓ ↓ ↓ ↓
import { useShallowStore as _useShallowStore } from "hooks";

As you can see, import name (useShallowStore) and the import source (import .. from 'hooks') is hard coded.

You can change these in your package.json file.

{
  ...
  "babelMacros": {

    "zustandMacro": {
      "useStore": {
        "importName": "useShallowStore",
        "importSource": "hooks"
      }
    }
  }
}

You are ready to go now.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文