Coder Social home page Coder Social logo

heo's Introduction

Heo

简单、优雅的 React hooks 状态管理方案

CI npm size

  • React Hooks 适用于 React Hooks 组件
  • 专注性能 减少额外 rerender,运行畅快
  • 1KB min+gz
  • 无依赖 仅仅使用了 React,无第三方库的依赖
  • 简单 只需会 React Hooks,即可上手
  • TypeScript 编写 完备的类型提示,轻松编写代码
  • 容易集成 可渐进式引入,与其他状态管理共存
  • 通用 组件、模块、应用以及服务端渲染
  • 灵活 基于 Context,轻松组合 Provider
  • 轻松迁移 它基于自定义 Hooks 创建

安装

npm install --save heo

Example

import React from 'react';
import { createContainer, useMethods } from 'heo';

function useCounter() {
  const [count, setCount] = React.useState(0);

  const methods = useMethods({
    increment() {
      setCount(count + 1);
    },
    decrement() {
      setCount(count - 1);
    },
  });

  return {
    count,
    methods,
  };
}

const CounterContainer = createContainer(useCounter);

function CounterDisplay() {
  const { count, methods } = CounterContainer.usePicker(['count', 'methods']);

  return (
    <div>
      {count}
      <button type="button" onClick={methods.increment}>
        ADD
      </button>
      <button type="button" onClick={methods.decrement}>
        MINUS
      </button>
    </div>
  );
}

function App() {
  return (
    <CounterContainer.Provider>
      <CounterDisplay />
    </CounterContainer.Provider>
  );
}

render(<App />, document.getElementById('root'));

API

createContainer(useHook)

import { createContainer, useFunction } from 'heo';

function useCustomHook() {
  const [value, setValue] = useState();
  const onChange = useFunction((e) => setValue(e.currentTarget.value));
  return {
    value,
    onChange,
  };
}

const Container = createContainer(useCustomHook);
// Container === { Provider, usePicker }

<Container.Provider>

Container.Provider 基本用法

function Parent() {
  return (
    <Container.Provider>
      <ChildComponent />
    </Container.Provider>
  );
}

function Parent1() {
  return (
    <Container.Provider>
      {(value) => {
        // const computed = doSomething(value);
        return <ChildComponent />;
      }}
    </Container.Provider>
  );
}

<Container.Provider initialState>

function useCustomHook(initialState = '') {
  const [value, setValue] = useState(initialState);
  // ...
}

function ParentComponent() {
  return (
    <Container.Provider initialState="value">
      <ChildComponent />
    </Container.Provider>
  );
}

Container.useSelector()

监听当前容器中选择后的值,若值发生改变,则触发 rerender

function ChildComponent() {
  const value = Container.useSelector((state) => state.value);
  return <span>{value}</span>;
}

Container.usePicker()

useSelector 的语法糖,更常用的写法

function ChildComponent() {
  const { value } = Container.usePicker(['value']);
  return <span>{value}</span>;
}

Container.withPicker()

usePicker 的高阶组件形式

function ChildComponent({ value }) {
  return <span>{value}</span>;
}

Container.withPicker(ChildComponent, ['value']);

useMethods & useFunction

持久化 functionHook

你可能会需要用 useCallback 记住一个回调,但由于内部函数必须经常重新创建,记忆效果不佳,导致子组件重复 render。对于复杂的子组件,重新渲染会对性能造成影响。通过 useMethods,可以保证函数地址永远不会变化。

性能提示

Heo 的灵感来自于 unstated-next,并解决了 unstated-next 中导致的 context 穿透的性能问题,而无需过量抽象组合优化组件。 在大型模块/项目中性能极其重要,它能为我们节省大量的调优时间。

导出成员记忆化

React Hooks 中,每一次 setState 会重新执行一遍当前的 function,也就是 rerender。在这个特性下,组件的内部 function 也会随着 rerender 而重新创建,表达式也会重新执行,useMemouseCallBack 也因此而存在。

Heo 的记忆特性也与 React 保持一致。在下方 useCounter 返回值中,函数需要 useMethods 包裹才能达到记忆效果。因此需要注意:不要导出会随着每次 render 而重新创建的可变对象Heo 无需优化,所有你要做的优化,都是标准的 React 优化。

function useCounter() {
  const [count, setCount] = React.useState(0);

  const methods = useMethods({
    increment() {
      setCount(count + 1);
    },
    decrement() {
      setCount(count - 1);
    },
    handleClick() {
      // 可通过 this 调用
      this.increment();
      // ...
    },
  });

  return {
    count,
    methods,
  };
}

const Counter = createContainer(useCounter);

License

MIT © MinJieLiu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.