Created
July 30, 2019 02:25
-
-
Save Jokcy/e0ae15357141bf4937e8662c7d7853a5 to your computer and use it in GitHub Desktop.
taro的redux在h5端不支持hooks,可以用这段代码来兼容
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Taro, { useEffect, useState, useRef } from '@tarojs/taro' | |
import * as tredux from '@tarojs/redux' | |
const env = Taro.getEnv() | |
const { WEB } = Taro.ENV_TYPE | |
let store | |
const refEquality = (a, b) => a === b | |
function h5useSelector(selector, equalityFn = refEquality) { | |
// useStoreChange() | |
const [, forceUpdate] = useState(0) | |
const latestSubscriptionCallbackError = useRef() | |
const latestSelector = useRef() | |
const latestSelectedState = useRef() | |
let selectedState | |
try { | |
if ( | |
selector !== latestSelector.current || | |
// 如果store变化的时候重新读取数据出错 | |
// 则在下次渲染重新尝试,如果还是不行,才真正抛出错误 | |
latestSubscriptionCallbackError.current | |
) { | |
selectedState = selector(store.getState()) | |
} else { | |
selectedState = latestSelectedState.current | |
} | |
} catch (err) { | |
let errorMessage = `An error occured while selecting the store state: ${err.message}.` | |
if (latestSubscriptionCallbackError.current) { | |
errorMessage += `\nThe error may be correlated with this previous error:\n${latestSubscriptionCallbackError.current.stack}\n\nOriginal stack trace:` | |
} | |
throw new Error(errorMessage) | |
} | |
useEffect(() => { | |
latestSelector.current = selector | |
latestSelectedState.current = selectedState | |
latestSubscriptionCallbackError.current = undefined | |
}) | |
useEffect(() => { | |
function checkForUpdates() { | |
try { | |
const newSelectedState = latestSelector.current(store.getState()) | |
if (equalityFn(newSelectedState, latestSelectedState.current)) { | |
return | |
} | |
latestSelectedState.current = newSelectedState | |
} catch (err) { | |
// we ignore all errors here, since when the component | |
// is re-rendered, the selectors are called again, and | |
// will throw again, if neither props nor store state | |
// changed | |
latestSubscriptionCallbackError.current = err | |
} | |
forceUpdate(a => a + 1) | |
} | |
// const listener = () => forceUpdate(a => a + 1) | |
store.subscribe(checkForUpdates) | |
return () => store.unSubscribe(checkForUpdates) | |
}, [store]) | |
return selector(store.getState()) | |
} | |
function h5useDispatch() { | |
const hooksStore = h5useStore() | |
return hooksStore.dispatch | |
} | |
function h5useStore() { | |
return store | |
} | |
const useSelectorName = 'useSelector' | |
export function useSelector(...args) { | |
if (env === WEB) { | |
return h5useSelector(...args) | |
} | |
// 避免webpack编译的warning | |
return tredux[useSelectorName](...args) | |
} | |
const useDispatchName = 'useDispatch' | |
export function useDispatch(...args) { | |
if (env === WEB) { | |
return h5useDispatch(...args) | |
} | |
// 避免webpack编译的warning | |
return tredux[useDispatchName](...args) | |
} | |
const useStoreName = 'useStore' | |
export function useStore(...args) { | |
if (env === WEB) { | |
return h5useStore(...args) | |
} | |
// 避免webpack编译的warning | |
return tredux[useStoreName](...args) | |
} | |
/** | |
* 都有的API就全部直接export | |
*/ | |
export const connect = tredux.connect | |
export const connectAdvanced = tredux.connectAdvanced | |
export function injectStore(s) { | |
store = s | |
store.subscribe(() => {}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment