immer api_集成immer js与use全局钩子

immer api

Immer.js is the winner of the “Breakthrough of the yearReact open source award and “Most impactful contributionJavaScript open source award in 2019. Combine it with use-global-hook and we have the most pleasant way to manage complex states I ever tried.

Immer.js在2019年荣获年度突破”, React开源奖和“最具影响力的贡献JavaScript开源奖。将它与use-global-hook结合使用,我们将以最愉快的方式来管理复杂状态我曾经尝试过。

Suppose that you have a complex state like:

假设您有一个复杂的状态,例如:

const state = {
  cities: [
    {
      name: "Chicago",
      state: "Illinois",
      population: [
        {
          year: 2020,
          population: 2713984
        }
      ],
      weatherStatus: {
        lat: 40.12,
        lon: -96.66,
        timezone: "America/Chicago",
        current: {
          temp: 293.28,
          wind_speed: 4.6,
          weather: [
            {
              id: 501,
              description: "Moderate rain",
              icon: "10n"
            }
          ]
        }
      }
    }
  ]
};

Before Immer, if you want to change: cities[0].weatherStatus.current.weather[0].description
You would need something like:

在Immer之前,如果要更改: cities[0].weatherStatus.current.weather[0].description
cities[0].weatherStatus.current.weather[0].description
您将需要以下内容:

const newWeatherItem = { ...state.cities[0].weatherStatus.current.weather[0], description: "Clear sky" }
const newWeather = [...state.cities[0].weatherStatus.current.weather]
newWeather[0] = newWeatherItem
const newCurrent = { ...state.cities[0].weatherStatus.current, weather: newWeather }
const newWeatherStatus = { ...state.cities[0].weatherStatus, current: newCurrent }
const newCities = [...state.cities]
newCities[0] = { ...newCities[0], weatherStatus: newWeatherStatus }


const newState = { ...state, cities: newCities }

Would life be easier if we could just do the following?

如果我们能做到以下几点,生活会更轻松吗?

store.setState((state) => {
    state.cities[0].weatherStatus.current.weather[0].description = "Clear sky";
 });

Yes, we can do it and the setup is very quick. Let’s do it!

是的,我们可以做到,并且设置非常快。 我们开始做吧!

Immer如何运作 (How does Immer works)

Image for post

Using Immer is like having a personal assistant; he takes a letter (the current state) and gives you a copy (draft) to jot changes onto. Once you are done, the assistant will take your draft and produce the real immutable, final letter for you (the next state).

使用Immer就像有个私人助理。 他拿了一封信(当前状态)并给了您一份副本(草稿)以将更改记入。 完成后,助手将为您准备草稿,并为您生成真正的不可变的最后一封信(下一个状态)。

You can add it to your project by running:

您可以通过运行以下命令将其添加到项目中:

npm install immer

use-global-hook如何工作 (How does use-global-hook works)

use-global-hook is a lightweight state management lib that does not need the redux boilerplate but keeps the flux pattern. That means you still create actions to change your state. Here is a minimal example:

use-global-hook是一个轻量级的状态管理库,它不需要redux样板文件,但可以保留磁通模式。 这意味着您仍然可以创建操作来更改状态。 这是一个最小的示例:

import React from 'react';
import globalHook from 'use-global-hook';
 
const initialState = {
  counter: 0,
};
 
const actions = {
  addToCounter: (store, amount) => {
    const newCounterValue = store.state.counter + amount;
    store.setState({ counter: newCounterValue });
  },
};
 
const useGlobal = globalHook(React, initialState, actions);
 
const App = () => {
  const [globalState, globalActions] = useGlobal();
  return (
    <div>
      <p>
        counter:
        {globalState.counter}
      </p>
      <button type="button" onClick={() => globalActions.addToCounter(1)}>
        +1 to global
      </button>
    </div>
  );
};
 
export default App;

You can add it to your project by running:

您可以通过运行以下命令将其添加到项目中:

npm install use-global-hook

将Immer与use-global-hook集成 (Integrating Immer with use-global-hook)

Starting on version 0.2.1, use-global-hook comes with the Immer integration out of the box. We just need to send the Immer lib as a dependency inside the use-global-hook options.

0.2.1版开始, use-global-hook随即提供了Immer集成。 我们只需要将Immer lib作为依赖项发送到use-global-hook选项中即可。

import React from "react";
import Immer from "immer";
import globalHook from "use-global-hook";
import * as actions from "../actions";
import { initialState } from "./initialState";


const options = { Immer };
const useGlobal = globalHook(React, initialState, actions, options);


export default useGlobal;

Now, let go back for the first weather example. To create an action to change the weather description, we can just:

现在,让我们回到第一个天气示例。 要创建一个更改天气描述的动作,我们可以:

export const changeWeatherDescription = (store, description) => {
  store.setState((state) => {
    state.cities[0].weatherStatus.current.weather[0].description = description;
  });
};

If your action returns a function, use-global-hook will execute it as an Immer function. For example, if you want an action that adds a number to the current population, you can write as:

如果您的操作返回一个函数,则use-global-hook会将其作为Immer函数执行。 例如,如果您想要一个将数字添加到当前人口的操作,则可以写为:

export const add1ToPopuation = (store) => (state) => {
  state.cities[0].population[0].population++;
};

If you want to check a full example, including async actions, you can check this CodeSandbox:

如果要检查完整的示例,包括异步操作,可以检查此CodeSandbox:

https://codesandbox.io/s/immer-integration-e1hpj

https://codesandbox.io/s/immer-integration-e1hpj

For more use-global-hook, you can also check the npm page:

有关更多use-global-hook的信息,您还可以查看npm页面:

普通英语JavaScript (JavaScript In Plain English)

Enjoyed this article? If so, get more similar content by subscribing to Decoded, our YouTube channel!

喜欢这篇文章吗? 如果是这样,请订阅我们的YouTube频道解码,以获得更多类似的内容

翻译自: https://medium.com/javascript-in-plain-english/integrating-immer-js-with-use-global-hook-4a1373d777a5

immer api

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值