Используйте «навигацию» и «маршрут» внутри заголовка, представленного в классе - React-navigation v5 - PullRequest
2 голосов
/ 18 февраля 2020

Я застрял, потому что хочу переключиться на версию V5 реагирующей навигации. С v4 я передавал свои параметры и использовал их с:

  • Set:

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

  • Получить:

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

В версии 5 некоторые вещи изменились, и теперь я не могу использовать this.props.navigation, так как приложение, кажется, не известно приложению.

Мой код разделен, поэтому у меня есть приложение. js, которое относится только к классу навигации:

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

А затем перейдите на каждую из моих страниц (закодированных с классами), и вот один пример, 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

Моя проблема заключается в том, что, согласно онлайн-документации, я видел, что для использования «навигации» или «маршрута» в классе я должен использовать const navigation = { this.props } после функция render().

Эта проблема заключается в том, что для использования одной определенной c функции в заголовке я должен связать ее после функция componentDidMount(), но значение в render() еще не известно.

Как я могу решить эту проблему? (Убедитесь, что в данном примере наличие всего кода в части навигации позволяет легко использовать navigation и route, но вы понимаете, что я должен разделить мой код.

Спасибо.

1 Ответ

2 голосов
/ 18 февраля 2020

Хорошо, поэтому каждый раз одно и то же, я стараюсь много дней решать свою проблему, и когда я наконец решаю разместить в стеке, я нахожу решение:).

Итак, если есть какая-то проблема с производительностью или другие вы можете увидеть, посмотрев на мой код, не стесняйтесь исправить меня. Я только что обнаружил, что это решение решило мою проблему.

Итак, в моем файле Navigation. js я просто передал объекты навигации и маршрута, чтобы сделать их пригодными для использования благодаря подпоркам в моих классах, например так:

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.navigation или this.props.route и собираю из этих объектов то, что мне нужно.

Другое дело, что для тех, кто будет использовать этот код чтобы создать нечто подобное, мне также пришлось изменить способ отображения кнопки заголовка. Я больше не пользуюсь static navigationOptions = () => {}. Я просто добавляю непосредственно кусок кода navigation.setOptions в функцию ComponentDidMount следующим образом:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...