1.3.0 • Published 2 years ago

@minko-fe/context-state v1.3.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

context-state

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

codesandbox

EXAMPLE

安装

yarn add @minko-fe/context-state

介绍

React Context 和 useContext 存在一些性能问题,当 context 上下文改变时,所有使用到 context 的组件都会更新渲染。 context-state 为解决性能问题而生。

v1.1.0 之前,它使用 calculateChangedBits 来阻止 context 更新,但这个 API 将会被 React 废弃。

v1.1.0 之后,将不再依赖 calculateChangedBits

Example

import React from 'react';
import { createContainer, useMemoizedFn } from '@minko-fe/context-state';

function useCounter() {
  const [count, setCount] = React.useState(0);
  const increment = useMemoizedFn(() => setCount((c) => c + 1));

  return {
    count,
    increment,
  };
}

const CounterContainer = createContainer(useCounter);

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

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

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

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

API

createContainer(useHook)

import { createContainer, useMemoizedFn } from '@minko-fe/context-state';

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

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

<Container.Provider>

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

<Container.Provider value>

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

function ParentComponent() {
  return (
    <Container.Provider value="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>;
}

useMemoizedFn

持久化 functionHook。(来自 ahooksuseMemoizedFn

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

灵感来源

unstated-next | use-context-selector

1.2.4

2 years ago

1.2.3

2 years ago

1.3.0

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.7

2 years ago