Skip to content

Instantly share code, notes, and snippets.

@Jokcy
Created July 30, 2019 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jokcy/e0ae15357141bf4937e8662c7d7853a5 to your computer and use it in GitHub Desktop.
Save Jokcy/e0ae15357141bf4937e8662c7d7853a5 to your computer and use it in GitHub Desktop.
taro的redux在h5端不支持hooks,可以用这段代码来兼容
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