在taro中使用useContext实现全局数据注入
发表时间:2021-1-11
发布人:葵宇科技
浏览次数:151
相信全局数据同步是每个前端开发都会遇到的问题,在实际开发过程中,比较常见的方式有redux, mobx, vuex等
然而,在使用了react hooks后,有一种更加简便优雅的方式,那就是使用useContext这个钩子
在普通的react项目中,我们可以很自然地使用useContext,但是,最近我们项目组打算使用taro重构项目,于是花了点功夫进行技术调研,踩了一些坑,所以还是写点总结,希望能给小伙伴们提供点帮助。
useContext的具体使用方式可以查看 官方文档
在taro 2.2.6版本中使用
在实际开发项目中,useContext的使用方式比较不太方便,于是借鉴了 unstated-next 这个库的源码,在本地创建了一个useContainer的hook,替换原来的React.createContext为Taro.createContext,然后就可以愉快地使用啦
- 步骤1: 创建useContainer.ts
import Taro from "@tarojs/taro";
const EMPTY: unique symbol = Symbol();
export interface ContainerProviderProps<State = void> {
initialState?: State;
children: any;
}
export interface Container<Value, State = void> {
Provider: any;
useContainer: () => Value;
}
export function createContainer<Value, State = void>(
useHook: (initialState?: State) => Value
): Container<Value, State> {
let Context = Taro.createContext<Value | typeof EMPTY>(EMPTY);
function Provider(props: ContainerProviderProps<State>) {
let value = http://www.wxapp-union.com/useHook(props.initialState);
return <Context.Provider value=http://www.wxapp-union.com/{value}>{props.children};
}
function useContainer(): Value {
let value = http://www.wxapp-union.com/Taro.useContext(Context);
if (value =http://www.wxapp-union.com/== EMPTY) {
throw new Error("Component must be wrapped with <Container.Provider>");
}
return value;
}
return { Provider, useContainer };
}
export function useContainer<Value, State = void>(
container: Container<Value, State>
): Value {
return container.useContainer();
}
复制代码
- 步骤2: 写一些需要在全局使用的数据
import { createContainer } from "./useContainer";
import { useState } from "@tarojs/taro";
export default createContainer(() => {
const [count, setCount] = useState(0);
// 这里可以做一些数据的获取操作,例如发送请求之类的
return {
count,
setCount,
};
})
复制代码
步骤3: 在入口文件app.tsx中,注入全局数据
import Container from "./hooks/index";
# 省略部分代码
Taro.render(
<Container.Provider>
<App />
</Container.Provider>,
document.getElementById("app")
);
复制代码
这里遇到的一个小坑就是,我们不能在 App
类里面写注入代码,因为那个render其实是没起实际作用的。
写到这里,似乎就大功告成了,写一下测试数据,运行npm run dev:h5,可以在组件和嵌套页面中正常显示我们注入的全局数据
然而,运行npm run dev:weapp,似乎在小程序中并不支持......
正巧在调研的时候Taro 3.0发布了,于是更新了一波taro,试试有没有支持
在taro 3.0.0-rc.6版本中使用
- 通过
taro update self
命令,我们将taro更新到最新的版本 taro init my-taro-demo
初始化一个项目- taro 3.0中内置了React,因此我们可以直接引入
unstated-next
这个包,不需要创建本地的useContainer - 重复步骤2
- 修改初始化项目中的app.ts为app.tsx( 划重点 ),修改app.tsx
import Container from "./hooks/container";
# 省略部分代码
render() {
return <Container.Provider>{this.props.children}</Container.Provider>;
}
复制代码
最后,分别运行npm run dev: h5 和 npm run dev:weapp,都能完美显示~