#javascript #reactjs #react-native
#javascript #reactjs ( реакция ) #реагировать-родной #reactjs #react-native
Вопрос:
У меня есть простой функциональный компонент с WebView внутри TabNavigator, в который я хотел бы ввести некоторый javascript, когда вкладка сфокусирована следующим образом:
import React, {useRef, useEffect} from 'react';
import {WebView} from 'react-native-webview';
export default (props) => {
const webViewRef = useRef();
React.useEffect(() => {
const unsubscribe = props.navigation.addListener('focus', () => {
webViewRef.current.injectJavascript('console.log("Hello World")');
});
return unsubscribe;
}, []);
return (
<WebView ref={webViewRef} />
);
}
По какой-то причине webViewRef
всегда не определено в слушателе.
Если я сделаю что-то вроде <WebView ref={(r) => console.log(r)} />
, я получу что-то вроде следующего:
Редактировать:
Простая настройка предоставленного примера работает, поэтому, я полагаю, мне придется выяснить, что происходит в моем коде:
import React, { useRef } from 'react'
import { View } from 'react-native'
import { WebView } from 'react-native-webview'
export default () => {
const webViewRef = useRef(null);
const run = `
document.body.style.backgroundColor = 'blue';
true;
`
setTimeout(() => {
webViewRef.current.injectJavaScript(run)
}, 3000)
return (
<View style={{ flex: 1 }}>
<WebView
ref={webViewRef}
source={{
uri:
'https://github.com/react-native-community/react-native-webview',
}}
/>
</View>
)
}
РЕДАКТИРОВАТЬ 2: Корректировка простого примера и попытка использовать ссылку внутри прослушивателя не работает:
import React, { useRef } from 'react'
import { View } from 'react-native'
import { WebView } from 'react-native-webview'
export default (props) => {
const webViewRef = useRef(null);
const run = `
document.body.style.backgroundColor = 'blue';
true;
`
const handleLoadEnd = () => {
props.navigation.addListener('focus', () => {
webViewRef.current.injectJavascript(run)
})
}
return (
<View style={{ flex: 1 }}>
<WebView
ref={webViewRef}
source={{
uri:
'https://github.com/react-native-community/react-native-webview',
}}
onLoadEnd={handleLoadEnd}
/>
</View>
)
}
Правка 3: useFocusEffect
также имеет ту же проблему:
useFocusEffect(
React.useCallback(() => {
webViewRef.current.injectJavascript('alert("HI")')
}, [props.navigation])
)
Источники:
Комментарии:
1. Не могли бы вы проверить, что вы можете получить доступ
webViewRef.current
из addListener?2. Это всегда кажется неопределенным, это так сбивает с толку.
3. Можете ли вы протестировать свой код с помощью setTimeout с задержкой 3000-5000 мс? Если ссылка все еще не определена, значит, что-то не так. А также вы можете создать эффект использования внутри массива, который вы передаете ref. Если он установлен, он будет вызван автоматически
4. В том, как это работает со слушателем, определенно есть что-то странное — поскольку я могу использовать ссылку, если она вызывается непосредственно внутри
useEffect
. В прослушивателе, даже с таймаутом, это не работает.
Ответ №1:
О боже, это действительно еще один из тех эпических дней, когда волосы тянутся:
webViewRef.injectJavascript < BAD
webViewRef.injectJavaScript < GOOD
Кто-нибудь, пожалуйста, верните последние 4 часа моей жизни
Комментарии:
1. спасибо вам за это, эта заглавная буква S в
JavaScript
действительно непослушна.2. Забавно, что сегодня у меня была одна из этих ужасных ситуаций с библиотекой, в которой нужной мне опции
lazyLoad
не былоlazyload
3. большое спасибо, чувак! Я буквально потратил часы, пытаясь решить эту проблему!
Ответ №2:
Ссылка будет установлена, если onLoadEnd
событие сработало. Итак, вы должны настроить свой код следующим образом:
export default (props) => {
const webViewRef = useRef();
const handleLoadEnd = () => {
props.navigation.addListener('focus', () => {
webViewRef.current.injectJavascript('console.log("Hello World")');
});
}
return (
<WebView ref={webViewRef} onLoadEnd={handleLoadEnd}/>
);
}
У меня есть рабочий пример. Смотрите здесь https://github.com/Tracer1337/MRGVP/blob/master/vertretungsplan/components/PaginatedWebview/PaginatedWebview.js
Комментарии:
1. Спасибо, это имеет смысл, и я добавил слушателя в
onLoadEnd
, но у меня все еще та же проблема,webViewRef
не определена:(2. Так что, к сожалению, это не работает, и я думаю, что это можно сузить до слушателя, пожалуйста, смотрите пример в
Edit 2
моем посте