業(yè)務(wù)場景
原生APP內(nèi)嵌h5應(yīng)用士败,h5(web)端使用react-hooks+redux。
注:本文只代表個人觀點
交互流程
原生與js進行交互的時候褥伴,如原生app登錄用戶返回的用戶數(shù)據(jù)傳遞給h5谅将,需要h5先使用一個方法向原生索要數(shù)據(jù)。但是用戶登錄登陸數(shù)據(jù)至關(guān)重要重慢,必須在原生進入h5頁面時已經(jīng)要獲取到數(shù)據(jù)饥臂,并以此數(shù)據(jù)為基礎(chǔ)進行接口請求,如accesstoken
安卓
安卓會直接在該方法獲取到的return的數(shù)據(jù)似踱。
如:
let user = getAndroidUser()
iOS
蘋果無法在方法里獲得return的數(shù)據(jù)隅熙,h5只能通過主動索要數(shù)據(jù),ios會提供另一個方法去注入數(shù)據(jù)到h5
如:
getIOSUser() //索要
getLoginInfoByNative() //被注入
當(dāng)getIOSUser()去索要數(shù)據(jù)時核芽,我們無法取得返回值囚戚。將getLoginInfoByNative()方法寫在redux的actions.js時,控制臺發(fā)現(xiàn)轧简,里邊的getLoginInfoByNative(result)方法內(nèi)經(jīng)過一定延時后的確得到了result的值(user數(shù)據(jù))驰坊,但是該方法的回調(diào)不能起作用,如下:
export function getLoginInfoByNative(user) {
console.log(user) //有返回值
//return無法執(zhí)行
return {
type: actionTypes.GET_LOGIN_INFO,
user
}
}
因為react是單向數(shù)據(jù)流哮独,且在但在單頁內(nèi)直接去同步代碼的時候拳芙,并不能直接監(jiān)聽到user數(shù)據(jù)并且同步到GET_LOGIN_INFO察藐,
//該做法無法成功
const action = {
type: 'GET_LOGIN_INFO',
user: user
}
store.dispatch(action)
解決方法
既然ios返回,中斷了我們的數(shù)據(jù)流舟扎,根據(jù)普通的做法是無法成功的了分飞。我們需要對ios進行單獨的做法。
一睹限、把接收ios函數(shù)回調(diào)的方法放在actions里會導(dǎo)致無法回調(diào)譬猫,所以我們把他提出去正常的方法里邊試試,顯然可以成功了羡疗。創(chuàng)建一個外部的js去放置以上方法删窒,方法可以進行回調(diào)。但是回調(diào)也沒法繼續(xù)執(zhí)行顺囊,那我們就換個辦法,獲取到user數(shù)據(jù)后蕉拢,直接存到本地緩存特碳,不存到store數(shù)據(jù)里。
export function getLoginInfoByNative(user) {
if (user!== undefined) {
console.log('ios的返回數(shù)據(jù)', user)
StorageUtils.setItem(StorageUtils.storageKey.iosUser, user)
}
}
二晕换、我們再去利用react-hooks的useEffect去監(jiān)聽外部的js類的數(shù)據(jù)源
const [IOSState, setIOSState] = useState()
useEffect(() => {
if (isIOSEnv()) {
getCurrentUser()
setIOSState(getLoginInfoByNative())
}
}, [])
useEffect(() => {
let iosUser = StorageUtils.getItem(StorageUtils.storageKey.iosUser)
if(iosUser){
const action = {
type: 'LOGIN_INFO',
iosUser: iosUser
}
store.dispatch(action)
}
}, [IOSState])
然后就成功解決了午乓,大致略寫,有空在完善
github相關(guān)問題傳送門:https://github.com/chendishen/bugList