react-native-webview-invoke icon indicating copy to clipboard operation
react-native-webview-invoke copied to clipboard

hooks 组件件 push一个新的webview返回旧的webview,旧webview invoke定义的原生方法丢失

Open zhaozedong opened this issue 4 years ago • 0 comments

import { StackHeaderOptions } from '@react-navigation/stack/lib/typescript/src/types'; import React, { useCallback, useContext, useEffect, useRef } from 'react'; import { View, Platform, StatusBar, Keyboard, BackHandler, KeyboardEvent, NativeModules, StatusBarStyle, AppState, AppStateStatus } from 'react-native'; import { _openCamera, _openPicker } from '../../moudles/tokenPhoto'; import WebView from 'react-native-webview'; import createInvoke, { IMessager } from 'react-native-webview-invoke/native'; import { _testwebviewUrl } from '../../config/url'; import askPermission from '../../moudles/AskPermission'; import { getLocation } from '../../moudles/Location'; import JPush from 'jpush-react-native'; import styles from './indexstyle'; import { StoreContext } from '../../store'; import LoadError from '../../components/LoadErr'; import { useFocusEffect, useIsFocused } from '@react-navigation/native';

let statusBarHeight: number | undefined = 20;

const _PLATFROM = Platform.OS;

if (_PLATFROM === 'ios') { NativeModules.StatusBarManager.getHeight((s:any) => { statusBarHeight = s.height; }); } else statusBarHeight = StatusBar.currentHeight;

function Home(props:any) {

const webviewRef = useRef<WebView<{}>>(null);
const Invoke: IMessager = createInvoke(()=>webviewRef.current); // 创建注入原生方法的实列
const { state } = useContext(StoreContext);
const isFocused = useIsFocused();

const _keyboardDidShow:(e:KeyboardEvent)=>void = (e) => {  // 键盘弹起
    const js = ` window.keyboardDidShow && window.keyboardDidShow(${ e.endCoordinates.height })`;
    webviewRef.current && webviewRef.current.injectJavaScript(js);
};
const _keyboardDidHide:()=>void = () => {  // 键盘收起
    const js = 'window.keyboardDidHide && window.keyboardDidHide()';
    webviewRef.current && webviewRef.current.injectJavaScript(js);
};
const _onBackHander:()=>boolean = ()=>{  // 物理返回键
    const js = 'window.onBackHander && window.onBackHander()';
    webviewRef.current && webviewRef.current.injectJavaScript(js);
    return true;
}
const _onAppState:(nextAppState:AppStateStatus)=>void = (nextAppState)=>{  //App前后台切换状态
    const currAppState = AppState.currentState;
    const js = `window.onAppState && window.onAppState(${currAppState},${nextAppState})`;
    webviewRef.current && webviewRef.current.injectJavaScript(js);
}
const _push = (url:string, data?:{[key:string]:any},headerOptions?:StackHeaderOptions):void=>{ // 打开一个新的webview
    console.log(99999)
   props.navigation.push('Home',{
       url,
       ...data,
       headerOptions
   })
};
const _pop = ()=>{ // 返回上一个路由栈
    props.navigation.goBack();
}
const _setBarStyle = (color:StatusBarStyle)=>{  // 设置状态栏字体颜色
    if(_PLATFROM == 'ios') NativeModules.Tools.setBarStyle(color);
    else StatusBar.setBarStyle(color);
}
const _getStatusBarHeight:()=>number | undefined = ()=>{  // 获取状态栏高度
    return statusBarHeight
};
const _exitApp:()=>void = ()=>{  // 退出app
    if(_PLATFROM == 'android') BackHandler.exitApp();
}
const _reload:()=>void = ()=>{  // 重新加载
    webviewRef.current?.reload();
}

useEffect(()=>{ //   定义注入webview的原生方法
    //  打开一个新的webview 
    Invoke.define('push',_push);
    //  回退路由栈
    Invoke.define('pop',_pop)  
    //  设置状态栏样式'default' | 'light-content' | 'dark-content';
    Invoke.define('setBarStyle', _setBarStyle);
    //  获取状态栏高度
    Invoke.define('getStatusBarHeight', _getStatusBarHeight);
    //  android  请求权限询问
    Invoke.define('askPermission', askPermission);

    // 选择相册
    Invoke.define('openPicker', _openPicker);
    // 拍照
    Invoke.define('openCamera', _openCamera);

    // 退出App
    Invoke.define('exitApp', _exitApp);
    // 重载
    Invoke.define('reload', _reload);
    // 定位
    Invoke.define('getLocation', getLocation);
 

},[]);

useEffect(()=>{  // 监听 (键盘 | 物理返回 | AppState | 推送监听)

    const keyboardDidShow = Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
    const keyboardDidHide = Keyboard.addListener("keyboardDidHide", _keyboardDidHide);

    const backHander = BackHandler.addEventListener('hardwareBackPress', _onBackHander);

    AppState.addEventListener('change', _onAppState);

    JPush.addNotificationListener(res => {
        let {url} = res.extras || {url: null},
          type = res.notificationEventType;
        if (type == 'notificationOpened' && url) {
          let json = JSON.stringify({url: url});
          const js = ` window.recievedPushMessage && window.recievedPushMessage(${json})`;
          webviewRef.current?.injectJavaScript(js);
        }
    });

    return () => {
        keyboardDidShow.remove();
        keyboardDidHide.remove();

        backHander.remove();

        AppState.removeEventListener('change', _onAppState);
        JPush.removeListener(()=>{});
    };
},[]);
useFocusEffect(useCallback(()=>{
    if(!isFocused){
        const js = ` window.screenIsFocused && window.screenIsFocused()`;
        webviewRef.current?.injectJavaScript(js);
    }
    
},[isFocused]))
let _webviewUrl: string = state?.webviewUrl || ''
_webviewUrl = _testwebviewUrl;
return(
    <View
        style={ styles.container }
    >
        { _PLATFROM == 'android' ?  <StatusBar  translucent={true} backgroundColor={'rgba(255,255,255,0)'} /> : null }
        <WebView
            ref={ webviewRef }
            style={{flex: 1}}
            sharedCookiesEnabled={true}
            useSharedProcessPool={true}
            source={{uri: props.route.params?.url || _webviewUrl }}  
            onLoadEnd={() => {}}
            mixedContentMode={'always'} // compatibility
            startInLoadingState={true}
            textZoom={100}
            allowsInlineMediaPlayback={true}
            scrollEnabled={ props.route.params?.scrollEnabled || false }
            onMessage={ Invoke.listener }
            renderError={()=>(
                <LoadError setBarStyle={ _setBarStyle } reload={ _reload }/>
            )}
        />   
    </View>
    
)

}

export default Home;

zhaozedong avatar Jan 18 '21 08:01 zhaozedong