在类中存在的标题内使用“导航"和“路由" - React-navigation v5 [英] Use 'navigation' and 'route' inside header present in class - React-navigation v5

查看:28
本文介绍了在类中存在的标题内使用“导航"和“路由" - React-navigation v5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被卡住了,因为我想切换到 V5 版本的 react-navigation.在 v4 中,我曾经传递我的参数并将它们用于:

I'm stuck as I want to switch to the V5 version of react-navigation. With v4, I used to pass my params and use them with :

  • 设置:

this.props.navigation.navigate('MyDestination', {myParam: 'value'})

  • 获取:

this.props.navigation.getParam('myParam')

在 v5 中,有些事情发生了变化,我现在无法使用 this.props.navigation,因为应用似乎不知道它.

With v5, some things changed and I now can't use the this.props.navigation since it's not seemed to be known by the app.

我的代码被拆分了,所以我的 App.js 只引用了 Navigation 类:

My code is splitted so I have my App.js that only refer to the Navigation 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,因为我想先修复基本导航):

Then my Navigation file contains all the navigation mechanism (I did not added my TabBar yet, since I want to fix the base navigation first) :

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

然后是我的每个页面(用类编码),这里有一个例子,Home.js(我删除了所有 Style 部分以缩短此处显示的代码):

And then come each of my pages (coded with classes), and here is one example, Home.js (I removed all the Style part to shorten the code displayed here) :

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

我的问题是,根据在线文档,我看到要在类中使用导航"或路由",我应该在render() 函数.

My problem is that, per the online documentation, I saw that to use "navigation" or "route" within a class, I should use the const navigation = { this.props } after the render() function.

这个问题是,要在标头中使用一个特定的函数,我必须在 componentDidMount() 函数之后绑定它,但是 render() 还不知道.

This problem is that, to use one specific function within the header, I have to bind it after the componentDidMount() function, but the value present under render() is not yet known.

我该如何解决这个问题?(确保在给定的示例中,导航部分中的所有代码允许轻松使用 navigationroute 但您知道我必须拆分我的代码.

How could I solve this ? (sure that in the given example, having all the code in the navigation part allow to use navigation and route easily but you understand that I have to split my code.

谢谢.

推荐答案

好的,所以每次都一样,我尝试了很多天解决我的问题,当我最终决定在堆栈上发布时,我找到了解决方案:).

Ok, so each time the same, I try many days solving my problem, and when I finally decide to post on stack, I find a solution :).

因此,如果您在查看我的代码时可能会发现一些性能问题或其他问题,请随时纠正我.我刚刚发现这个解决方案解决了我的问题.

So, if there's some performance issue or other you may see by looking at my code, do not hesitate to correct me. I just found that this solution solved my problem.

所以在我的 Navigation.js 文件中,我只是传递了导航和路由对象以使它们可用,这要归功于我的类中的道具,如下所示:

So within my Navigation.js file, I just passed the navigation and route objects to make them usable thanks to the props into my classes, like this :

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>
)}

然后在我的课程中,我只需调用 this.props.navigationthis.props.route 并从这些对象中收集我需要的东西.

then within my classes I just call to this.props.navigation or this.props.route and gather form these objects what I need.

另一件事是,对于那些将使用此代码构建类似内容的人,我还必须更改显示标题按钮的方式.我不使用 static navigationOptions = () =>{} 了.我只是在 ComponentDidMount 函数中直接添加 navigation.setOptions 一段代码,如下所示:

Other thing is that, for those who would use this code to build something similar, I also had to change the way I display the header button. I do not use the static navigationOptions = () => {} anymore. I just add directly the navigation.setOptions piece of code within the ComponentDidMount function like this:

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>
        })

我必须这样做,因为我使用的是在我的类中声明的函数,所以我必须像这样在构造函数中绑定它 this._goToSettings = this._goToSettings.bind(this),然后将其添加到 navigation.setParams 函数中.

I have to do it this way since I'm using a function declared in my class, so I have to bind it in the constructor like this this._goToSettings = this._goToSettings.bind(this) and then add it to the navigation.setParams function.

这篇关于在类中存在的标题内使用“导航"和“路由" - React-navigation v5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆