diff --git a/README.md b/README.md index 5300b1a..5c0b87a 100644 --- a/README.md +++ b/README.md @@ -22,39 +22,7 @@ import { taroStorage } from 'foca-taro-storage'; class App extends Component { render() { - return ( - // 注意:是个匿名函数 - {() => this.props.children} - ); + return {this.props.children}; } } ``` - -### 路由 - -关注 taro 官方 issue https://github.com/NervJS/taro/issues/6548#issuecomment-717896033 ,需要在`首页`加入拦截器以保证数据的稳定性 - -```typescript -import { persistInterceptor } from 'foca-taro-storage'; - -// 写法1 -@persistInterceptor -export class HomePage extends Component {} - -// 写法2 -class HomePage extends Component {} -export default persistInterceptor(HomePage); - -// 写法3 -const HomePage: FC = (props) => {}; -export default persistInterceptor(HomePage); -``` - -如果你的某些页面需要分享给用户,则`分享入口`文件也需要搭配拦截器。 - -```typescript -import { persistInterceptor } from 'foca-taro-storage'; - -@persistInterceptor -export class MySharePage extends Component {} -``` diff --git a/package.json b/package.json index de9983f..0bf5fca 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,6 @@ "foca": ">=0.11.0", "react": ">=16.9.0" }, - "dependencies": { - "hoist-non-react-statics": "^3.3.2" - }, "devDependencies": { "@commitlint/cli": "^16.2.4", "@commitlint/config-conventional": "^16.2.4", diff --git a/src/hoc.tsx b/src/hoc.tsx deleted file mode 100644 index b2c49e9..0000000 --- a/src/hoc.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { store } from 'foca'; -import hoistStatics from 'hoist-non-react-statics'; -import React, { ComponentType, useEffect, useState, FC } from 'react'; - -// 路由入口没有ref的需求,所以不需要增加forwardRef -export function persistInterceptor(EntryComponent: ComponentType) { - const HOC: FC = (props) => { - const state = useState(store.isReady); - const ready = state[0]; - - useEffect(() => { - ready || - store.onInitialized().then(() => { - state[1](true); - }); - }, []); - - return ready ? : null; - }; - - return hoistStatics(HOC, EntryComponent); -} diff --git a/src/index.ts b/src/index.ts index 562a814..99ad98a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ +import './override'; export { taroStorage } from './storage'; -export { persistInterceptor } from './hoc'; diff --git a/src/override.ts b/src/override.ts new file mode 100644 index 0000000..e412f62 --- /dev/null +++ b/src/override.ts @@ -0,0 +1,39 @@ +import { store } from 'foca'; +import { Component } from 'react'; + +/** + * @link https://developers.weixin.qq.com/miniprogram/dev/framework/runtime/js-support.html + * 摘自微信小程序的文档: + * 由于实现原因与 iOS JavaScriptCore 限制,iOS 环境下的 Promise 是一个使用 setTimeout 模拟的 Polyfill。 + * 这意味着 Promise 触发的任务为普通任务,而非微任务,进而导致 在 iOS 下的 Promise 时序会和标准存在差异。 + * + * @link https://github.com/NervJS/taro/issues/6548 + * 路由页(包括首页)mount后,taro会立即寻找根结点。但由于恢复持久化需要时间,导致页面报错(没有找到页面实例。) + * + * @link https://github.com/NervJS/taro/blob/next/packages/shared/src/native-apis.ts#L263 + * 查看源码得知,getStorage在taro底层已经直接进行了Promise化处理。 + * 在以往的版本中,曾经尝试使用`getStorageSync`去代替,但是效果不佳。 + * + * @link https://github.com/NervJS/taro/blob/next/packages/taro-plugin-react/src/runtime/connect.ts#L200 + * forceUpdate可能是同步的也可能是异步的,但getStorage一定是异步的。 + * 所以根据mount的逻辑,我们需要重写forceUpdate使得寻找节点的回调在恢复持久化之后才被执行。 + */ + +const forceUpdate = Component.prototype.forceUpdate; + +Component.prototype.forceUpdate = function ( + this: Component, + callback?: () => void, +) { + forceUpdate.call( + this, + callback && + (() => { + if (store.isReady) { + callback(); + } else { + store.onInitialized().then(callback); + } + }), + ); +}; diff --git a/src/storage.ts b/src/storage.ts index e946596..79b9a5e 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -8,17 +8,15 @@ import { export const taroStorage: StorageEngine = { getItem(key) { - return getStorage({ key }) - .then(({ data }) => data) - .then( - (data) => { - return typeof data === 'string' ? data : null; - }, - () => { - // 使用getStorage()找不到key时,Taro会抛出异常: getStorage:fail data not found - return null; - }, - ); + return getStorage({ key }).then( + ({ data }) => { + return typeof data === 'string' ? data : null; + }, + () => { + // 使用getStorage()找不到key时,Taro会抛出异常: getStorage:fail data not found + return null; + }, + ); }, setItem(key, value) { return setStorage({