用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

在taro中使用useContext實現全局數據注入

Rolan 2020-7-9 00:47

相信全局數據同步是每個前端開發都會遇到的問題,在實際開發過程中,比較常見的方式有redux, mobx, vuex等然而,在使用了react hooks后,有一種更加簡便優雅的方式,那就是使用useContext這個鉤子在普通的react項目 ...

相信全局數據同步是每個前端開發都會遇到的問題,在實際開發過程中,比較常見的方式有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 = useHook(props.initialState);
    return <Context.Provider value={value}>{props.children}</Context.Provider>;
  }

  function useContainer(): Value {
    let value = Taro.useContext(Context);
    if (value === 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,都能完美顯示~

鮮花
鮮花
雞蛋
雞蛋
分享至 : QQ空間
收藏
原作者: linliqzh 來自: 掘金
快乐十分复式