Ich habe eine Seite, auf der der Name des Benutzers angezeigt wird, wenn er angemeldet ist, oder die Option "Konto erstellen" oder "Anmelden", wenn er nicht angemeldet ist. Bildschirm wie unten
Sie können zur Seite "Anmelden" oder "Konto erstellen" navigieren. Nach erfolgreicher Anmeldung oder Registrierung navigiert es zu dieser Seite und zeigt den Benutzernamen an. Bildschirm wie unten
Derzeit speichere ich Benutzerdaten in AsyncStorage
. Ich möchte dieses Feld aktualisieren, sobald sich der Benutzer erfolgreich angemeldet oder registriert hat, wenn er von der Seite umleitet.
Wie kann ich das erreichen?
Gibt es eine Möglichkeit, Parameter von zu übergeben, navigate.goBack()
und Eltern können die Parameter abhören und ihren Status aktualisieren?
quelle
static navigationOptions = ({navigation}) => ({ headerRight: <Button title="test" onPress={() => navigation.navigate('GoToScreen', {onGoBack: () => this.refresh()})} /> });
, ärgert es mich, dass es keine gibtthis.refresh()
. Irgendwelche Lösungen?onGoBack: this.refresh
anstelle vononGoBack: () => this.refresh()
useEffect(refresh, [route.params?.updateTime])
und im untergeordneten Element.navigate("parent", {updateTime: new Date().getTime()})
.Sie können eine Rückruffunktion als Parameter übergeben (wie in anderen Antworten erwähnt).
Hier ist ein klareres Beispiel : Wenn Sie von A nach B navigieren und möchten, dass B Informationen an A zurückgibt, können Sie einen Rückruf übergeben (hier
onSelect
):ViewA.js
import React from "react"; import { Button, Text, View } from "react-native"; class ViewA extends React.Component { state = { selected: false }; onSelect = data => { this.setState(data); }; onPress = () => { this.props.navigate("ViewB", { onSelect: this.onSelect }); }; render() { return ( <View> <Text>{this.state.selected ? "Selected" : "Not Selected"}</Text> <Button title="Next" onPress={this.onPress} /> </View> ); } }
ViewB.js
import React from "react"; import { Button } from "react-native"; class ViewB extends React.Component { goBack() { const { navigation } = this.props; navigation.goBack(); navigation.state.params.onSelect({ selected: true }); } render() { return <Button title="back" onPress={this.goBack} />; } }
Hut ab für Debrice - Siehe https://github.com/react-navigation/react-navigation/issues/288#issuecomment-315684617
Bearbeiten
ViewB.js
import React from "react"; import { Button } from "react-native"; class ViewB extends React.Component { goBack() { const { navigation, route } = this.props; navigation.goBack(); route.params.onSelect({ selected: true }); } render() { return <Button title="back" onPress={this.goBack} />; } }
quelle
undefined is not an object (evaluating navigation.state.params.onSelect)
ist keine Funktion,this.props.route.params.onSelect
Versuchen Sie dies für diejenigen, die nicht über Requisiten verwalten möchten. Es wird jedes Mal aufgerufen, wenn diese Seite angezeigt wird.
import { NavigationEvents } from 'react-navigation'; render() { return ( <View style={{ flex: 1 }}> <NavigationEvents onWillFocus={() => { // Do your things here }} /> </View> ); }
quelle
Ich hatte ein ähnliches Problem. Deshalb habe ich es hier gelöst, indem ich näher auf Details eingegangen bin.
Option 1 besteht darin, mit Parametern zurück zum übergeordneten Element zu navigieren. Definieren Sie einfach eine Rückruffunktion wie folgt in der übergeordneten Komponente :
updateData = data => { console.log(data); alert("come back status: " + data); // some other stuff };
und navigiere zum Kind:
onPress = () => { this.props.navigation.navigate("ParentScreen", { name: "from parent", updateData: this.updateData }); };
Jetzt im Kind kann es genannt werden:
this.props.navigation.state.params.updateData(status); this.props.navigation.goBack();
Option zwei. Um Daten von einer Komponente abzurufen, kann AsyncStorage, wie in der anderen Antwort erläutert, entweder synchron verwendet werden oder nicht.
Sobald die Daten gespeichert sind, können sie überall verwendet werden.
// to get AsyncStorage.getItem("@item") .then(item => { item = JSON.parse(item); this.setState({ mystate: item }); }) .done(); // to set AsyncStorage.setItem("@item", JSON.stringify(someData));
oder verwenden Sie entweder eine asynchrone Funktion, um sie selbst zu aktualisieren, wenn sie auf diese Weise einen neuen Wert erhält.
this.state = { item: this.dataUpdate() }; async function dataUpdate() { try { let item = await AsyncStorage.getItem("@item"); return item; } catch (e) { console.log(e.message); } }
Weitere Informationen finden Sie in den AsyncStorage-Dokumenten .
quelle
BEARBEITET: Die beste Lösung ist die Verwendung von NavigationEvents . Sie müssen keine Listener manuell erstellen :)
Das Aufrufen einer Rückruffunktion wird nicht dringend empfohlen. Überprüfen Sie dieses Beispiel mit einem Listener (Denken Sie daran, alle Listener mit dieser Option aus componentWillUnMount zu entfernen.)
Komponente A.
Komponente B.
Weitere Informationen zum vorherigen Beispiel: https://github.com/react-navigation/react-navigation/issues/288#issuecomment-378412411
Grüße, Nicholls
quelle
Ich habe gerade die Standardnavigationsfunktion verwendet, die den Namen der ViewA-Route angibt und die Parameter übergibt. Ich habe genau das getan, was goBack getan hätte.
this.props.navigation.navigate("ViewA", { param1: value1, param2: value2 });
quelle
goBack()
. Dies geht weiter zur vorherigen Ansicht (es wird dem Stapel hinzugefügt). Und außerdem glaube ich nicht, dass dies die Frage beantwortet.this.props.navigation.navigate
ist der gleiche wie der AufrufgoBack()
. Probieren Sie es aus, Sie werden sehen. Die Bildschirmanimation wird von links nach rechts verschoben.navigation.navigate
immer eine Route auf den Stapel geschoben wurde.Wenn Sie verwenden
redus
, können Sie eine Aktion zum Speichern von Daten und Überprüfen des Werts im übergeordneten Element erstellenComponent
oder verwendenAsyncStorage
.Aber ich denke, es ist besser, nur
JSON-serializable
Parameter zu übergeben, denn wenn Sie eines Tages den Navigationsstatus speichern möchten, ist dies nicht sehr einfach.Beachten Sie
react-navigation
auch, dass diese Funktion in experimentellem https://reactnavigation.org/docs/en/state-persistence.html enthalten istIch mag diese Funktion im Entwicklungsmodus und wenn ich Parameter als Funktion übergebe, kann ich sie einfach nicht verwenden
quelle
Erster Bildschirm
updateData=(data)=>{ console.log('Selected data',data) } this.props.navigation.navigate('FirstScreen',{updateData:this.updateData.bind(this)})
Zweiter Bildschirm
// use this method to call FirstScreen method execBack(param) { this.props.navigation.state.params.updateData(param); this.props.navigation.goBack(); }
quelle
Ich würde auch navigation.navigate verwenden. Wenn jemand das gleiche Problem hat und auch verschachtelte Navigatoren verwendet , würde dies folgendermaßen funktionieren:
quelle
Verwenden Sie in React Navigation v5 einfach die Navigationsmethode. Aus den Dokumenten :
Vollständiges Beispiel:
import React from 'react'; import { StyleSheet, Button, Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); function ScreenA ({ navigation, route }) { const { params } = route; return ( <View style={styles.container}> <Text>Params: {JSON.stringify(params)}</Text> <Button title='Go to B' onPress={() => navigation.navigate('B')} /> </View> ); } function ScreenB ({ navigation }) { return ( <View style={styles.container}> <Button title='Go to A' onPress={() => { navigation.navigate('A', { data: 'Something' }) }} /> </View> ); } export default function App() { return ( <NavigationContainer> <Stack.Navigator mode="modal"> <Stack.Screen name="A" component={ScreenA} /> <Stack.Screen name="B" component={ScreenB} /> </Stack.Navigator> </NavigationContainer> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
quelle