业务场景
原生APP内嵌h5应用,h5(web)端使用react-hooks+redux。
注:本文只代表个人观点
交互流程
原生与js进行交互的时候,如原生app登录用户返回的用户数据传递给h5,需要h5先使用一个方法向原生索要数据。但是用户登录登陆数据至关重要,必须在原生进入h5页面时已经要获取到数据,并以此数据为基础进行接口请求,如accesstoken
安卓
安卓会直接在该方法获取到的return的数据。
如:
let user = getAndroidUser()
iOS
苹果无法在方法里获得return的数据,h5只能通过主动索要数据,ios会提供另一个方法去注入数据到h5
如:
getIOSUser() //索要
getLoginInfoByNative() //被注入
当getIOSUser()去索要数据时,我们无法取得返回值。将getLoginInfoByNative()方法写在redux的actions.js时,控制台发现,里边的getLoginInfoByNative(result)方法内经过一定延时后的确得到了result的值(user数据),但是该方法的回调不能起作用,如下:
export function getLoginInfoByNative(user) {
console.log(user) //有返回值
//return无法执行
return {
type: actionTypes.GET_LOGIN_INFO,
user
}
}
因为react是单向数据流,且在但在单页内直接去同步代码的时候,并不能直接监听到user数据并且同步到GET_LOGIN_INFO,
//该做法无法成功
const action = {
type: 'GET_LOGIN_INFO',
user: user
}
store.dispatch(action)
解决方法
既然ios返回,中断了我们的数据流,根据普通的做法是无法成功的了。我们需要对ios进行单独的做法。
一、把接收ios函数回调的方法放在actions里会导致无法回调,所以我们把他提出去正常的方法里边试试,显然可以成功了。创建一个外部的js去放置以上方法,方法可以进行回调。但是回调也没法继续执行,那我们就换个办法,获取到user数据后,直接存到本地缓存,不存到store数据里。
export function getLoginInfoByNative(user) {
if (user!== undefined) {
console.log('ios的返回数据', user)
StorageUtils.setItem(StorageUtils.storageKey.iosUser, user)
}
}
二、我们再去利用react-hooks的useEffect去监听外部的js类的数据源
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相关问题传送门:https://github.com/chendishen/bugList