在 class - React-navigation v5 中的 header 中使用 'navigation' 和 'route'
Use 'navigation' and 'route' inside header present in class - React-navigation v5
我卡住了,因为我想切换到 react-navigation 的 V5 版本。
使用 v4,我过去常常传递我的参数并将它们与 :
一起使用
- 设置:
this.props.navigation.navigate('MyDestination', {myParam: 'value'})
- 获取:
this.props.navigation.getParam('myParam')
在 v5 中,有些事情发生了变化,我现在无法使用 this.props.navigation
,因为应用程序似乎不知道它。
我的代码被拆分了,所以我的 App.js 只涉及导航 class :
import React from 'react';
import { StyleSheet, Text, View } from 'react-native'
import Navigation from './navigation/Navigation'
export default function App() {
return (
<Navigation/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
然后我的导航文件包含所有导航机制(我还没有添加我的 TabBar,因为我想先修复基本导航):
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { createBottomTabNavigator } from 'react-navigation-tabs'
import { StyleSheet, Image } from 'react-native'
import React from 'react'
import Home from '../components/Home'
import LendList from '../components/LendList'
import AddMoney from '../components/AddMoney'
import AddStuff from '../components/AddStuff'
import Settings from '../components/Settings'
import Test from '../components/Test'
function HomeScreen() {
return(
<Home/>
)
}
function LendListScreen() {
return(
<LendList/>
)
}
const Stack = createStackNavigator()
function App() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home"
component={Home}
options={{ title: "Home Page"}}
/>
<Stack.Screen name="LendList"
component={LendList}
options={{ title: 'Liste' }}
/>
<Stack.Screen name="AddMoney"
component={AddMoney}
options={{ title: "Ajout Money"}}
/>
<Stack.Screen name="AddStuff"
component={AddStuff}
options={{ title: "Ajout Stuff"}}
/>
<Stack.Screen name="Settings"
component={Settings}
options={{ title: "Settings"}}
/>
<Stack.Screen name="Test"
component={Test}
options={{ title: "Test"}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default App
然后是我的每个页面(用 classes 编码),这里是一个示例,Home.js(我删除了所有样式部分以缩短此处显示的代码):
import React from 'react'
import { StyleSheet, Text, Image, View, Button, TouchableOpacity } from 'react-native'
import Moment from 'react-moment'
import { CommonActions } from '@react-navigation/native'
import { useNavigation } from '@react-navigation/native'
class Home extends React.Component {
static navigationOptions = () => {
return {
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => this.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
}
}
constructor(props) {
super(props)
this._goToSettings = this._goToSettings.bind(this)
}
_updateNavigationParams() {
navigation.setParams({
goToSettings: this._goToSettings
})
}
componentDidMount(){
console.log("navigation")
this._updateNavigationParams()
}
_checkMoneyDetails(navigation){
navigation.navigate('LendList', {type: 'Money'})
}
_checkStuffDetails(navigation){
navigation.navigate('LendList', {type: 'Stuff'})
}
_checkPeopleDetails(navigation){
navigation.navigate('LendList', {type: 'People'})
}
_goToSettings = () => {
navigation.navigate('Settings')
}
render(){
const date = new Date();
const { navigation } = this.props;
return(
<View style={styles.main_container}>
<View style={styles.header_view}>
<Text style={styles.header_text}>GiViToMe</Text>
<Text style={styles.header_text}>Nous sommes le :{' '}
{/* TODO: Penser à gérer ensuite les formats de date étrangers */}
<Moment element={Text} format="DD/MM/YYYY" date={date}/>
</Text>
</View>
<View style={styles.lend_view}>
<Text style={styles.title_lend_text}>Vos prêts :</Text>
<View style={styles.money_stuff_view}>
<View style={styles.money_view}>
<View style={styles.money_data_view}>
<Image source={require('../assets/ic_money.png')} style={styles.home_img} />
<Text>XXX $</Text>
</View>
<Button title='Money' onPress={() => {this._checkMoneyDetails(navigation)}}/>
</View>
<View style={styles.stuff_view}>
<View style={styles.stuff_data_view}>
<Image source={require('../assets/ic_box.png')} style={styles.home_img} />
<Text>XXX objets</Text>
</View>
<Button title='Stuff' onPress={() => {this._checkStuffDetails(navigation)}}/>
</View>
</View>
<View style={styles.people_view}>
<View style={styles.people_data_view}>
<Image source={require('../assets/ic_people.png')} style={styles.home_img} />
<Text>XXX people</Text>
</View>
<Button title='People' onPress={() => {this._checkPeopleDetails(navigation)}}/>
</View>
</View>
<View style={styles.footer_view}>
<Text style={styles.text_footer_view}>a.vescera inc.</Text>
</View>
</View>
)
}
}
export default Home
我的问题是,根据在线文档,我看到要在 class 中使用 "navigation" 或 "route",我应该在 const navigation = { this.props }
之后使用render()
函数。
这个问题是,要在 header 中使用一个特定的函数,我必须在 componentDidMount()
函数之后绑定它,但是 render()
下的值还没有已知。
我该如何解决这个问题? (确保在给定的示例中,导航部分中的所有代码都允许轻松使用 navigation
和 route
,但你明白我必须拆分我的代码。
谢谢。
好的,所以每次都一样,我尝试了很多天来解决我的问题,当我最终决定 post 堆栈时,我找到了解决方案:)。
因此,如果您在查看我的代码时发现了一些性能问题或其他问题,请随时纠正我。我刚发现这个解决方案解决了我的问题。
所以在我的 Navigation.js 文件中,我刚刚传递了导航和路线 objects 使它们可用,这要归功于我的 classes 中的道具,如下所示:
function App() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home"
component={Home}
options={({route, navigation}) => (
{headerTitle: 'Home Page',
route: {route},
navigation: {navigation}}
)}
/>
</Stack.Navigator>
</NavigatorContainer>
)}
然后在我的 classes 中,我只需调用 this.props.navigation
或 this.props.route
并从这些 objects 中收集我需要的东西。
另一件事是,对于那些将使用此代码构建类似内容的人,我还必须更改显示 header 按钮的方式。
我不再使用 static navigationOptions = () => {}
了。我只是直接在 ComponentDidMount
函数中添加 navigation.setOptions
段代码,如下所示:
navigation.setOptions({
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => route.params.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
})
我必须这样做,因为我使用的是在我的 class 中声明的函数,所以我必须像这样 this._goToSettings = this._goToSettings.bind(this)
在构造函数中绑定它,然后将它添加到navigation.setParams
函数。
当navigation.setOptions
代码写在componentDidMount
里面时,在navigation
和route
关键字前加上this.props
。下面是对我有用的代码片段。
this.props.navigation.setOptions({
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => this.props.route.params.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
})
我卡住了,因为我想切换到 react-navigation 的 V5 版本。 使用 v4,我过去常常传递我的参数并将它们与 :
一起使用- 设置:
this.props.navigation.navigate('MyDestination', {myParam: 'value'})
- 获取:
this.props.navigation.getParam('myParam')
在 v5 中,有些事情发生了变化,我现在无法使用 this.props.navigation
,因为应用程序似乎不知道它。
我的代码被拆分了,所以我的 App.js 只涉及导航 class :
import React from 'react';
import { StyleSheet, Text, View } from 'react-native'
import Navigation from './navigation/Navigation'
export default function App() {
return (
<Navigation/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
然后我的导航文件包含所有导航机制(我还没有添加我的 TabBar,因为我想先修复基本导航):
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { createBottomTabNavigator } from 'react-navigation-tabs'
import { StyleSheet, Image } from 'react-native'
import React from 'react'
import Home from '../components/Home'
import LendList from '../components/LendList'
import AddMoney from '../components/AddMoney'
import AddStuff from '../components/AddStuff'
import Settings from '../components/Settings'
import Test from '../components/Test'
function HomeScreen() {
return(
<Home/>
)
}
function LendListScreen() {
return(
<LendList/>
)
}
const Stack = createStackNavigator()
function App() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home"
component={Home}
options={{ title: "Home Page"}}
/>
<Stack.Screen name="LendList"
component={LendList}
options={{ title: 'Liste' }}
/>
<Stack.Screen name="AddMoney"
component={AddMoney}
options={{ title: "Ajout Money"}}
/>
<Stack.Screen name="AddStuff"
component={AddStuff}
options={{ title: "Ajout Stuff"}}
/>
<Stack.Screen name="Settings"
component={Settings}
options={{ title: "Settings"}}
/>
<Stack.Screen name="Test"
component={Test}
options={{ title: "Test"}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default App
然后是我的每个页面(用 classes 编码),这里是一个示例,Home.js(我删除了所有样式部分以缩短此处显示的代码):
import React from 'react'
import { StyleSheet, Text, Image, View, Button, TouchableOpacity } from 'react-native'
import Moment from 'react-moment'
import { CommonActions } from '@react-navigation/native'
import { useNavigation } from '@react-navigation/native'
class Home extends React.Component {
static navigationOptions = () => {
return {
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => this.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
}
}
constructor(props) {
super(props)
this._goToSettings = this._goToSettings.bind(this)
}
_updateNavigationParams() {
navigation.setParams({
goToSettings: this._goToSettings
})
}
componentDidMount(){
console.log("navigation")
this._updateNavigationParams()
}
_checkMoneyDetails(navigation){
navigation.navigate('LendList', {type: 'Money'})
}
_checkStuffDetails(navigation){
navigation.navigate('LendList', {type: 'Stuff'})
}
_checkPeopleDetails(navigation){
navigation.navigate('LendList', {type: 'People'})
}
_goToSettings = () => {
navigation.navigate('Settings')
}
render(){
const date = new Date();
const { navigation } = this.props;
return(
<View style={styles.main_container}>
<View style={styles.header_view}>
<Text style={styles.header_text}>GiViToMe</Text>
<Text style={styles.header_text}>Nous sommes le :{' '}
{/* TODO: Penser à gérer ensuite les formats de date étrangers */}
<Moment element={Text} format="DD/MM/YYYY" date={date}/>
</Text>
</View>
<View style={styles.lend_view}>
<Text style={styles.title_lend_text}>Vos prêts :</Text>
<View style={styles.money_stuff_view}>
<View style={styles.money_view}>
<View style={styles.money_data_view}>
<Image source={require('../assets/ic_money.png')} style={styles.home_img} />
<Text>XXX $</Text>
</View>
<Button title='Money' onPress={() => {this._checkMoneyDetails(navigation)}}/>
</View>
<View style={styles.stuff_view}>
<View style={styles.stuff_data_view}>
<Image source={require('../assets/ic_box.png')} style={styles.home_img} />
<Text>XXX objets</Text>
</View>
<Button title='Stuff' onPress={() => {this._checkStuffDetails(navigation)}}/>
</View>
</View>
<View style={styles.people_view}>
<View style={styles.people_data_view}>
<Image source={require('../assets/ic_people.png')} style={styles.home_img} />
<Text>XXX people</Text>
</View>
<Button title='People' onPress={() => {this._checkPeopleDetails(navigation)}}/>
</View>
</View>
<View style={styles.footer_view}>
<Text style={styles.text_footer_view}>a.vescera inc.</Text>
</View>
</View>
)
}
}
export default Home
我的问题是,根据在线文档,我看到要在 class 中使用 "navigation" 或 "route",我应该在 const navigation = { this.props }
之后使用render()
函数。
这个问题是,要在 header 中使用一个特定的函数,我必须在 componentDidMount()
函数之后绑定它,但是 render()
下的值还没有已知。
我该如何解决这个问题? (确保在给定的示例中,导航部分中的所有代码都允许轻松使用 navigation
和 route
,但你明白我必须拆分我的代码。
谢谢。
好的,所以每次都一样,我尝试了很多天来解决我的问题,当我最终决定 post 堆栈时,我找到了解决方案:)。
因此,如果您在查看我的代码时发现了一些性能问题或其他问题,请随时纠正我。我刚发现这个解决方案解决了我的问题。
所以在我的 Navigation.js 文件中,我刚刚传递了导航和路线 objects 使它们可用,这要归功于我的 classes 中的道具,如下所示:
function App() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home"
component={Home}
options={({route, navigation}) => (
{headerTitle: 'Home Page',
route: {route},
navigation: {navigation}}
)}
/>
</Stack.Navigator>
</NavigatorContainer>
)}
然后在我的 classes 中,我只需调用 this.props.navigation
或 this.props.route
并从这些 objects 中收集我需要的东西。
另一件事是,对于那些将使用此代码构建类似内容的人,我还必须更改显示 header 按钮的方式。
我不再使用 static navigationOptions = () => {}
了。我只是直接在 ComponentDidMount
函数中添加 navigation.setOptions
段代码,如下所示:
navigation.setOptions({
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => route.params.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
})
我必须这样做,因为我使用的是在我的 class 中声明的函数,所以我必须像这样 this._goToSettings = this._goToSettings.bind(this)
在构造函数中绑定它,然后将它添加到navigation.setParams
函数。
当navigation.setOptions
代码写在componentDidMount
里面时,在navigation
和route
关键字前加上this.props
。下面是对我有用的代码片段。
this.props.navigation.setOptions({
headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
onPress={() => this.props.route.params.goToSettings()}>
<Image style={styles.settings_image}
source={require('../assets/ic_settings.png')} />
</TouchableOpacity>
})