React Native中通过导航按钮刷新WebView的问题排查
这个问题我太熟悉了,你踩的坑是静态属性里的this和类实例的this完全不是一回事!
为什么会报错?
你把headerRight定义成了类的静态属性,静态成员是属于TheClass这个类本身的,不属于任何一个类的实例。而你写的onPress是类的实例方法,this.state也是实例的状态——在静态属性里用this,指向的是类本身,根本找不到onPress方法和state,所以才会抛出“Cannot read property 'onPress' of undefined”的错误。
正确的实现方案
我们需要把导航栏的配置放到navigationOptions里,并且用函数形式的navigationOptions,通过组件的navigation对象打通导航栏和实例方法的关联。直接看修改后的完整代码:
'use strict'; import React, { Component } from 'react'; import { Text, WebView } from 'react-native'; export default class TheClass extends Component<{}> { constructor() { super(); this.state = { url: 'https://www.google.com' }; } // 把navigationOptions改成函数,接收navigation参数 static navigationOptions = ({ navigation }) => ({ title: 'Example', headerRight: ( <Text onPress={() => navigation.getParams('handleRefresh')()}>Refresh</Text> ), }); componentDidMount() { // 组件挂载时,把实例的刷新方法传给导航参数 this.props.navigation.setParams({ handleRefresh: this.onPress, }); } onPress = () => { // 如果只是刷新WebView,其实不用改url,直接调用reload更高效 this.webView.reload(); // 要是你确实需要重置url,再用下面这行: // this.setState({ url: this.state.url }); }; render() { return ( <WebView ref={(ref) => (this.webView = ref)} // 给WebView加ref,方便调用reload source={{uri: this.state.url}} /> ); } }
关键知识点拆解
- 函数式navigationOptions:这种写法能让我们拿到
navigation对象,这是连接导航栏和组件实例的桥梁。 - setParams传递方法:在
componentDidMount里把实例的onPress方法存到导航参数里,这样导航栏的按钮就能通过getParams拿到这个方法并调用。 - WebView刷新优化:如果你的需求只是刷新网页,给WebView加个
ref调用reload()比修改state.url更直接高效,毕竟url本身没变化。
内容的提问来源于stack exchange,提问作者iEmad
相关产品推荐
相关产品推荐

