在这篇文章中,我们将带领您了解React-Native--可继承的Navigator的全貌,包括react类继承的相关情况。同时,我们还将为您介绍有关reactnativeNavigator、reac
在这篇文章中,我们将带领您了解React-Native -- 可继承的Navigator的全貌,包括react类继承的相关情况。同时,我们还将为您介绍有关react native Navigator、react native navigator 的使用、React Native Paper Provider 和 React Navigation NavigationContainer 在 React Native Web 中导致错误、React Native 之createDrawerNavigator和createSwitchNavigator的知识,以帮助您更好地理解这个主题。
本文目录一览:- React-Native -- 可继承的Navigator(react类继承)
- react native Navigator
- react native navigator 的使用
- React Native Paper Provider 和 React Navigation NavigationContainer 在 React Native Web 中导致错误
- React Native 之createDrawerNavigator和createSwitchNavigator
React-Native -- 可继承的Navigator(react类继承)
React-Native中Navigator的继承问题
最近使用React-Native开发程序,在使用Navigator的时候,发现Navigato无法继承。主要原因:Navigator是通过React.CreateClass创建的,与ES6支持的extends并不能很好地兼容,继承的时候不能覆盖相应的方法。
使用google在 http://www.jianshu.com/p/08d7d9e34957 中找到了解决方法。大致的思路就是在renderScene中对需要覆盖的方法进行重新的赋值。
不过,这样使用方式不太适合复用。于是重新封装成了一个可继承的Navigator。
备注:React-Native 版本为0.39.2
import React,{Component} from 'react'; import { Navigator } from 'react-native'; export default class CanOverrideNavigator extends React.Component { render() { return ( <Navigator {...this.props} renderScene={(route,navigator) =>this._renderScene(route,navigator)} />); } _renderScene(route,navigator) { this.overrideMethodFunc(navigator); return this.props.renderScene(route,navigator) } //设置继承方法 overrideMethodFunc(navigator) { if (this.overrideMethod) { return; } //保存navigator原有的函数 this._jumpBack = navigator.jumpBack; this._jumpForward = navigator.jumpForward; this._jumpTo = navigator.jumpTo; this._push = navigator.push; this._pop = navigator.pop; this._replace = navigator.replace; this._replaceAtIndex = navigator.replaceAtIndex; this._replacePrevIoUs = navigator.replacePrevIoUs; this._resetTo = navigator.resetTo; this._immediatelyResetRouteStack = navigator.immediatelyResetRouteStack; this._popToRoute = navigator.popToRoute; this._popToTop = navigator.popToTop; this._getCurrentRoutes = navigator.getCurrentRoutes; //对navigator的函数进行重新的赋值 navigator.jumpBack = ()=> { this.jumpBack(); }; navigator.jumpForward = ()=> { this.jumpForward(); }; navigator.jumpTo = (route)=> { this.jumpTo(route); }; navigator.push = (route)=> { this.push(route); }; navigator.pop = ()=> { this.pop(); }; navigator.replace = (route)=> { this.replace(route); }; navigator.replaceAtIndex = (route,index,cb)=> { this.replaceAtIndex(route,cb); }; navigator.replacePrevIoUs = (route)=> { this.replacePrevIoUs(route); }; navigator.resetTo = (route)=> { this.resetTo(route); }; navigator.immediatelyResetRouteStack = (routeStack)=> { this.immediatelyResetRouteStack(routeStack); }; navigator.popToRoute = (route)=> { this.popToRoute(route); }; navigator.popToTop = ()=> { this.popToTop(); }; navigator.getCurrentRoutes = ()=> { this.getCurrentRoutes(); }; this.overrideMethod = true; } jumpBack() { this._jumpBack(); } jumpForward() { this._jumpForward(); } jumpTo(route) { this._jumpTo(route); } push(route) { this._push(route); } pop() { this._pop(); } replace(route) { this._replace(route); } replaceAtIndex(route,cb) { this._replaceAtIndex(route,cb); } replacePrevIoUs(route) { this._replacePrevIoUs(route); } resetTo(route) { this._resetTo(route); } immediatelyResetRouteStack(routeStack) { this._immediatelyResetRouteStack(routeStack); } popToRoute(route) { this._popToRoute(route); } popToTop() { this._popToTop(); } getCurrentRoutes() { return this._getCurrentRoutes(); } }
使用方式
import React,{Component} from 'react'; import CanOverrideNavigator from './CanOverrideNavigator'; import { View,Text,TouchableHighlight,Navigator } from 'react-native'; export default class TestNavigator extends React.Component { render() { return ( <MyNavigator ref="navigator" initialRoute={{component: OneContainer}} configureScene={()=> { return Navigator.SceneConfigs.PushFromright; }} renderScene={this._renderScene.bind(this)} /> ); } _renderScene(route,navigator) { let Component = route.component; return ( <Component navigator={navigator} route={route} /> ) } } class MyNavigator extends CanOverrideNavigator { push(rotue) { console.log('before push'); super.push(rotue); console.log("after push"); } pop() { console.log('before pop'); super.pop(); console.log("after pop"); } } class OneContainer extends React.Component { render() { return (<TouchableHighlight style={{padding:20}} onPress={()=> { this.props.navigator.push({component: TwoContainer}) }} > <Text>OneContainer</Text> </TouchableHighlight>); } } class TwoContainer extends React.Component { render() { return (<TouchableHighlight style={{padding:20}} onPress={()=> { this.props.navigator.pop() }} > <Text>TwoContainer</Text> </TouchableHighlight>); } }
react native Navigator
下面代码来自http://www.lcode.org/%E3%80%90react-native%E5%BC%80%E5%8F%91%E3%80%91react-native%E6%8E%A7%E4%BB%B6%E4%B9%8Bnavigator%E7%BB%84%E4%BB%B6%E8%AF%A6%E8%A7%A3%E4%BB%A5%E5%8F%8A%E5%AE%9E%E4%BE%8B23/
/** * 导航器组件实例 * https://github.com/facebook/react-native */ 'use strict'; import React,{ AppRegistry,Component,StyleSheet,Text,View,TouchableHighlight,Navigator,} from 'react-native'; class NavButton extends React.Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } class NavMenu extends React.Component { render() { return ( <View style={styles.scene}> <Text style={styles.messageText}>{this.props.message}</Text> <NavButton onPress={() => { this.props.navigator.push({ message: '向右拖拽关闭页面',sceneConfig: Navigator.SceneConfigs.FloatFromright,}); }} text="从右边向左切入页面(带有透明度变化)" /> <NavButton onPress={() => { this.props.navigator.push({ message: '向下拖拽关闭页面',sceneConfig: Navigator.SceneConfigs.FloatFromBottom,}); }} text="从下往上切入页面(带有透明度变化)" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="页面弹出(回退一页)" /> <NavButton onPress={() => { this.props.navigator.popToTop(); }} text="页面弹出(回退到最后一页)" /> </View> ); } } class NavigatorDemo extends Component { render() { return ( <Navigator style={styles.container} initialRoute={{ message: '初始页面',}} renderScene={ (route,navigator) => <NavMenu message={route.message} navigator={navigator} />} configureScene={(route) => { if (route.sceneConfig) { return route.sceneConfig; } return Navigator.SceneConfigs.FloatFromBottom; }} /> ); } } const styles = StyleSheet.create({ container: { flex: 1,},messageText: { fontSize: 17,fontWeight: '500',padding: 15,marginTop: 50,marginLeft: 15,button: { backgroundColor: 'white',borderBottomWidth: StyleSheet.hairlinewidth,borderBottomColor: '#CDCDCD',}); AppRegistry.registerComponent('NavigatorDemo',() => NavigatorDemo);
运行报错,navigator is deprecated and has been removed。
打开当前目录,
npm install react-native-deprecated-custom-components --save
import {Navigator} from 'react-native-deprecated-custom-components';
修改后代码如下
'use strict'; import React,{Component} from 'react'; import { AppRegistry,} from 'react-native'; import {Navigator} from 'react-native-deprecated-custom-components'; class NavButton extends Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } class NavMenu extends React.Component { render() { return ( <View style={styles.scene}> <Text style={styles.messageText}>{this.props.message}</Text> <NavButton onPress={() => { this.props.navigator.push({ message: '向右拖拽关闭页面',}); }} text="从右边向左切入页面(带有透明度变化)" /> <NavButton onPress={() => { this.props.navigator.push({ message: '向下拖拽关闭页面',}); }} text="从下往上切入页面(带有透明度变化)" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="页面弹出(回退一页)" /> <NavButton onPress={() => { this.props.navigator.popToTop(); }} text="页面弹出(回退到最后一页)" /> </View> ); } } class NavigatorDemo extends Component { render() { return ( <Navigator style={styles.container} initialRoute={{ message: '初始页面',}} renderScene={ (route,navigator) => <NavMenu message={route.message} navigator={navigator} />} configureScene={(route) => { if (route.sceneConfig) { return route.sceneConfig; } return Navigator.SceneConfigs.FloatFromBottom; }} /> ); } } const styles = StyleSheet.create({ container: { flex: 1,messageText: { fontSize: 17,button: { backgroundColor: 'white',}); AppRegistry.registerComponent('testrn',() => NavigatorDemo);
react native navigator 的使用
import React,{ Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} from 'react-native';
// 使用Component的好处是,可以自动生成注释
class FirstPage extends Component {
// 填出提示框
onPress(){
//alert("This is Shining!");
this.props.navigator.pop();
}
/**
* 跳转页面至SecondPage
* @param name 传递参数
* @param type 动画类型
*/
gotoNext(name,type = 'normal') {
this.props.navigator.push({
component: SecondPage,
passprops: {
id: name
},
onPress: this.onPress.bind(this),
rightText: 'ALERT!',
type: type
})
}
render() {
// 点击按钮使用Home页面入栈
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={()=>this.gotoNext('第一页')}>
<Text style={styles.buttonText}>
{'跳转至第二页(右出)'}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={()=>this.gotoNext('第一页','Modal')}>
<Text style={styles.buttonText}>
{'跳转至第二页(底部)'}
</Text>
</TouchableOpacity>
</View>
);
}
}
/**
* 第二页
*/
class SecondPage extends Component {
nextPageOnpress = ()=>{
// alert('第三页导航栏rightButton click');
this.props.navigator.push({
component:SecondPage,
passprops: {
id: '临时第yi页'
}
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={()=>this.props.navigator.pop()}>
<Text style={styles.buttonText}>
返回上一页,来源: {this.props.id}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={()=>this.props.navigator.push({
component:ThirdPage,
passprops:{
name:'3rd Page'
},
title:'第三页标题',
rightText:'HIHI',
onPress:this.nextPageOnpress,
type:'Modal',
})}>
<Text style={styles.buttonText}>
跳转至下一页
</Text>
</TouchableOpacity>
</View>
);
}
}
class ThirdPage extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={()=>this.props.navigator.pop()}>
<Text style={styles.buttonText}>
Third Page Now,+ {this.props.name}
</Text>
</TouchableOpacity>
</View>
);
}
}
// 导航栏的Mapper
var NavigationBarRouteMapper = {
// 左键
LeftButton(route,navigator,index,navstate){
if (index > 0) {
return (
<View style={styles.navContainer}>
<TouchableOpacity
underlayColor='transparent'
onPress={()=> {if (index >0) { navigator.pop()}}}>
<Text style={styles.leftNavButtonText}>
Back
</Text>
</TouchableOpacity>
</View>
);
} else {
return null;
}
},
// 右键
RightButton(route,navstate) {
if (route.onPress)
return (
<View style={styles.navContainer}>
<TouchableOpacity
onPress={() => route.onPress()}>
<Text style={styles.rightNavButtonText}>
{route.rightText || '右键'}
</Text>
</TouchableOpacity>
</View>
);
},
// 标题
Title(route,navstate){
return (
<View style={styles.navContainer}>
<Text style={styles.title}>
{route.title || 'Application Title'}
</Text>
</View>
);
}
};
// 主模块
class UniformView extends Component {
/**
* 使用动态页面加载
* @param route 路由
* @param navigator 导航器
* @returns {XML} 页面
*/
renderScene(route,navigator) {
return <route.component navigator={navigator} {...route.passprops} />;
}
configureScene(route,routeStack){
if (route.type == 'Modal') {
return Navigator.SceneConfigs.FloatFromBottom;
}
return Navigator.SceneConfigs.PushFromright;
}
render() {
return (
<Navigator
style={{flex:1}}
initialRoute={{name:'FirstPage',component:FirstPage}}
configureScene={this.configureScene}
renderScene={this.renderScene}
navigationBar={
<Navigator.NavigationBar
style={styles.navContainer}
routeMapper={NavigationBarRouteMapper}/>}
/>
);
}
}
const styles = StyleSheet.create({
// 页面框架
container: {
flex: 4,
marginTop: 100,
flexDirection: 'column',
backgroundColor: 'yellow'
},
// 导航栏
navContainer: {
backgroundColor: '#81c04d',
paddingTop: 12,
paddingBottom: 10,
},
// 导航栏文字
headText: {
color: '#ffffff',
fontSize: 22
},
// 按钮
button: {
height: 60,
marginTop: 10,
justifyContent: 'center',// 内容居中显示
backgroundColor: '#ff1049',
alignItems: 'center'
},
// 按钮文字
buttonText: {
fontSize: 18,
color: '#ffffff'
},
// 左面导航按钮
leftNavButtonText: {
color: '#ffffff',
fontSize: 18,
marginLeft: 13
},
// 右面导航按钮
rightNavButtonText: {
color: '#ffffff',
marginRight: 13
},
// 标题
title: {
fontSize: 18,
color: '#fff',
textAlign: 'center',
alignItems: 'center',
fontWeight: 'bold',
flex: 1 //Step 3
}
});
AppRegistry.registerComponent('TheTenth',() => UniformView);
React Native Paper Provider 和 React Navigation NavigationContainer 在 React Native Web 中导致错误
如何解决React Native Paper Provider 和 React Navigation NavigationContainer 在 React Native Web 中导致错误?
我是 React-native 和 React-native-web 的初学者。我目前正在处理一个使用 React-Native-paper
和 @react-navigation/native
库的现有项目。我正在尝试使用现有代码/项目作为 Web 应用程序运行。但是当我在 App.js 中使用以下代码时,我在运行 Web 应用程序的控制台中收到一个错误:
import React from ''react'';
import {Provider} from ''react-native-paper'';
import {NavigationContainer} from ''@react-navigation/native'';
export const App = props => {
return (
<NavigationContainer>
<Provider>
<Navigator />
</Provider>
</NavigationContainer>
);
};
我得到的错误是:
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
at AppContainer (webpack://web_tester/./node_modules/react-native-web/dist/exports/AppRegistry/AppContainer.js?:22:24)
react-dom.development.js:14906 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This Could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at Object.throwInvalidHookError (VM231 react-dom.development.js:14906)
at Object.useContext (VM227 react.development.js:1504)
at eval (VM252 index.js:83)
at renderWithHooks (VM231 react-dom.development.js:14985)
at updateForwardRef (VM231 react-dom.development.js:17044)
at beginWork (VM231 react-dom.development.js:19098)
at HTMLUnkNownElement.callCallback (VM231 react-dom.development.js:3945)
at Object.invokeGuardedCallbackDev (VM231 react-dom.development.js:3994)
at invokeGuardedCallback (VM231 react-dom.development.js:4056)
at beginWork$1 (VM231 react-dom.development.js:23959)
我创建了一个包含错误的简单 git repository。请看一下。
任何其他方面的见解都会有所帮助。并提前致谢。
解决方法
尝试将 react-native-paper 提供程序放在外面。我的应用使用以下代码使用 react-native 和 react-native-web 工作正常。
我已经通过 Expo which is the recommended way 设置了 react-native-web:引用自 react-native-web 文档:“通常建议您使用 Expo。”
<PaperProvider theme={theme} settings={settings}>
<NavigationContainer>
<RootStackScreens />
</NavigationContainer>
</PaperProvider>
React Native 之createDrawerNavigator和createSwitchNavigator
其他代码接上篇文章
createDrawerNavigator 抽屉
createSwitchNavigator 模拟登录=>主界面
index.js
/**
* @format
*/
import {AppRegistry} from ''react-native'';
import {createAppContainer} from ''react-navigation'';
import App from ''./navigators/AppNavigators'';
import {name as appName} from ''./app.json'';
AppRegistry.registerComponent(appName, () => App);
AppNavigators.js


import React from ''react''; //只要在页面中使用了基础组件 都需要导入这句话 不然会报错
import {Button,Platform,ScrollView,SafeAreaView} from ''react-native'';
import { createStackNavigator,
createAppContainer,
createBottomTabNavigator,
createMaterialTopTabNavigator,
createDrawerNavigator,
DrawerItems,
createSwitchNavigator,
} from ''react-navigation'';
import HomePage from ''../pages/HomePage'';
import Page1 from ''../pages/Page1'';
import Page2 from ''../pages/Page2'';
import Page3 from ''../pages/Page3'';
import Page4 from ''../pages/Page4'';
import Page5 from ''../pages/Page5'';
import Login from ''../pages/Login'';
import Ionicons from ''react-native-vector-icons/Ionicons''
import MaterialIcons from ''react-native-vector-icons/MaterialIcons''
const DrawerNav=createDrawerNavigator(
{
Page4:{
screen:Page4,
navigationOptions:{
drawerLabel:''Page4'',
drawerIcon:({tintColor})=>(
<MaterialIcons
name={''drafts''}
size={24}
style={{color:tintColor}}
/>
)
}
},
Page5:{
screen:Page5,
navigationOptions:{
drawerLabel:''Page5'',
drawerIcon:({tintColor})=>(
<MaterialIcons
name={''move-to-inbox''}
size={24}
style={{color:tintColor}}
/>
)
}
}
},
{
initialRouteName:''Page4'',
contentOptions:{
activeTintColor:''#e91e63'',
},
contentComponent:(props)=>(
<ScrollView style={{backgroundColor:''#789'',flex:1}}>
<SafeAreaView forceInset={{top:''always'',horizontal:''never''}}>
<DrawerItems {...props}/>
</SafeAreaView>
</ScrollView>
)
}
);
const AppTopNavigator=createMaterialTopTabNavigator(
{
Page1:{
screen:Page1,
navigationOptions:{
tabBarLabel: ''All''
}
},
Page2:{
screen:Page2,
navigationOptions:{
tabBarLabel: ''iOS''
}
},
Page3:{
screen:Page3,
navigationOptions:{
tabBarLabel: ''Android''
}
},
Page4:{
screen:Page4,
navigationOptions:{
tabBarLabel: ''React-Native''
}
},
},
{
tabBarOptions:{
tabStyle:{mindWidth: 50},
upperCaseLabel:false,//是否使标签大写 默认true
scrollEndabled:true,//是否支持选项卡滚动 默认false
style:{
backgroundColor:''#678''//TabBar背景色
},
indicatorStyle:{
height:2,
backgroundColor:''white''
},//标签指示器样式
labelStyle:{
fontSize:13,
marginTop:6,
marginBottom:6
},// 文字的样式
}
}
);
const AppBottomNavigator=createBottomTabNavigator(
{
Page1:{
screen:Page1,
navigationOptions:{
tabBarLabel: ''最热'',
tabBarIcon:({tintColor,focused})=>(<Ionicons
name={''ios-home''}
size={26}
style={{color:tintColor}}
/>)
}
},
Page2:{
screen:Page2,
navigationOptions:{
tabBarLabel: ''趋势'',
tabBarIcon:({tintColor,focused})=>(<Ionicons
name={''ios-appstore''} // 全部小写
size={26}
style={{color:tintColor}}
/>)
}
},
Page3:{
screen:Page3,
navigationOptions:{
tabBarLabel: ''收藏'',
tabBarIcon:({tintColor,focused})=>(<Ionicons
name={''ios-people''}
size={26}
style={{color:tintColor}}
/>)
}
},
Page4:{
screen:Page4,
navigationOptions:{
tabBarLabel: ''我的'',
tabBarIcon:({tintColor,focused})=>(<Ionicons
name={''ios-aperture''}
size={26}
style={{color:tintColor}}
/>)
}
},
},
{
tabBarOptions:{
activeTintColor: Platform.OS === ''ios'' ? ''#e91e63'' : ''#fff'',
}
}
);
const AppStack = createStackNavigator({
Home: {
screen: HomePage
},
Page1: {
screen: Page1
},
Page2: {
screen: Page2,
navigationOptions: {//在这里定义每个页面的导航属性,静态配置
title: "This is Page2.",
}
},
Page3: {
screen: Page3,
navigationOptions: (props) => {//在这里定义每个页面的导航属性,动态配置
const {navigation} = props;
const {state, setParams} = navigation;
const {params} = state;
return {
title: params.title ? params.title : ''This is Page3'',
headerRight: (
<Button
title={params.mode === ''edit'' ? ''保存'' : ''编辑''}
onPress={()=>{setParams({mode: params.mode === ''edit'' ? '''' : ''edit''})}
}
/>
),
}
}
},
Bottom:{
screen:AppBottomNavigator,
navigationOptions:{
title:''BottomNavigator''
}
},
Top:{
screen:AppTopNavigator,
navigationOptions:{
title:''TopNavigator''
}
},
DrawerNav:{
screen:DrawerNav,
navigationOptions:{
title:''This is DrawNavigator'',
}
}
},
{
defaultNavigationOptions: {
// header: null,// 可以通过将header设为null 来禁用StackNavigator的Navigation Bar
}
}
);
const AuthStack = createStackNavigator({
Login: {
screen: Login
},
},{
navigationOptions: {
// header: null,// 可以通过将header设为null 来禁用StackNavigator的Navigation Bar
}
});
const AppStackNavigator = createSwitchNavigator(
{
Auth: AuthStack,
App: AppStack,
},
{
initialRouteName: ''Auth'',
}
);
const App = createAppContainer(AppStackNavigator)
export default App
Login.js


/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, {Fragment,Component} from ''react'';
import {
StyleSheet,
View,
Text,
Button,
} from ''react-native'';
export default class Login extends Component {
render(){
const {navigation}=this.props;
return (
<View style={styles.container}>
<Text style={styles.welcome}>欢迎来到Login</Text>
<Button
title={''Go App''}
onPress={()=>{
navigation.navigate(''App'');
}}
/>
</View>
);
}
}
const styles=StyleSheet.create({
container:{
flex:1,
},
welcome:{
fontSize:20,
textAlign: ''center'',
}
});
效果图
今天关于React-Native -- 可继承的Navigator和react类继承的讲解已经结束,谢谢您的阅读,如果想了解更多关于react native Navigator、react native navigator 的使用、React Native Paper Provider 和 React Navigation NavigationContainer 在 React Native Web 中导致错误、React Native 之createDrawerNavigator和createSwitchNavigator的相关知识,请在本站搜索。
本文标签: