unstated-next状态管理库
背景
在React写应用的时候,难免遇到跨组件通信的问题。现在已经有很多的解决方案。
- React本身的Context
- Redux结合React-redux
- Mobx结合mobx-react
React 的新的Context api本质上并不是React或者Mbox这种状态管理工具的替代品,充其量只是对React自身状态管理短板的补充。而Redux和Mbox这两个库本身并不是为React设计的,对于一些小型的React应用比较重。
基本概念
Unstated是基于context API。也就是使用React.createContext()创建一个StateContext来传递状态,
- Container:状态管理类,内部使用state存储状态,通过setState实现状态的更新,api设计与React的组件基本一致。
- Provider:返回Provider,用来包裹顶层组件,向应用中注入状态管理实例,可做数据的初始化。
- Subscribe:本质上是Consumer,获取状态管理实例,在Container实例更新状态的时候强制更新视图。
安装
npm install --save unstated-next
yarn add unstated-next
创建container
store/index.js
import React, { useState } from 'react';
import { createContainer } from 'unstated-next';
const useStore = (
//初始化数据
initialState = {
//端内数据
isGrounds: false,
statusBarHeight: 0,
// 自定义全局数据
events: [],
},
) => {
const [states, setStates] = useState(initialState);
const changeStates = newStates => {
setStates(states => Object.assign({}, states, newStates));
};
return { states, changeStates };
};
export const Store = createContainer(useStore);
使用Provider包裹
Layout/index.jsx
import React from 'react';
import { Store } from './store';
import Tabber from './component/Tabber';
const Layout = () => {
return (
<Store.Provider>
<Tabber />
</Store.Provider>
);
};
export default Layout;
使用container
component/Tabber/index.jsx
import React from 'react';
import { Store } from '../../store';
const Tabber = () => {
// 获取全局数据
const store = Store.useContainer();
const { states } = store;
//监听
const handleFlexClick = () => {
console.log('点击跳转目标页面');
};
return (
<div>
<div onClick={handleFlexClick}>热门榜</div>
</div>
);
};
export default Tabber;
小结
一句话概括:将你自定义的hook传入context。
优点:简单
缺点:
一言以蔽之,这个简单的小函数并不能妥善处理状态比较多的页面管理。
声明一个共享的状态就要手动创建一个自定义hooks,然后在其最外层包裹一个Provider组件,操作太麻烦,不利于开发。 如果多个状态都使用一个hooks管理,内部状态没有隔离很容易出现bug,同时context会造成没必要的渲染。