#javascript #react-native #react-navigation
#javascript #реагировать-родной #react-навигация
Вопрос:
Когда я нажимаю кнопку «Назад» или выполняю this.props.navigation.goBack()
, я возвращаюсь к своему первому экрану вместо первого экрана.
вот мой App.js был ли реализован мой навигатор:
export default class App extends React.Component {
render() {
const MainNavigator = createAppContainer(createBottomTabNavigator({
info: {
screen: CtrlInfoStart,
navigationOptions: { tabBarVisible: false }
},
mascotChoice: {
screen: CtrlMascotChoice,
navigationOptions: { tabBarVisible: false }
},
optionScreen: {
screen: CtrlOptions,
navigationOptions: { tabBarVisible: false }
},
welcomeScreen: {
screen: CtrlWelcome,
navigationOptions: { tabBarVisible: false }
},
preview: {
screen: CtrlPreviewMap,
navigationOptions: { tabBarVisible: false }
},
map: {
screen: CtrlMap,
navigationOptions: { tabBarVisible: false }
},
pointOfInterest: {
screen: CtrlPI,
navigationOptions: { tabBarVisible: false }
},
quizz: {
screen: CtrlQuizz,
navigationOptions: { tabBarVisible: false }
}
}));
return (
<View style={styles.container}>
<MainNavigator/>
</View>
);
}
};
Я использую this.props.navigation.navigate('SomeScreen');
для навигации между экранами и this.props.navigation.goBack()
для возврата назад.
Ответ №1:
Импорт BackHandler
из react native,
в componentdidmount
backhandler
событии привязки с использованием BackHandler.addEventListner()
смотрите это,
componentDidmount=()=>{
BackHandler.addEventListener("hardwareBackPress", this.handleBackButton);
}
componentWillUnmount = () => {
BackHandler.removeEventListener("hardwareBackPress", this.handleBackButton);
};
handleBackButton = () => {
this.props.navigation.navigate('SomeScreen');
return true;
};
И везде, где вы использовали goBack()
, измените его с помощью navigate("ScreenName")
Редактировать:
для непредвиденного поведения на других экранах сделайте это там, где используется backhander.
import {NavigationEvents} "react-navigation";
при рендеринге внутри первого компонента,
<NavigationEvents onWillFocus={this.compnentDidmount} onWillBlur={this.componentWillUnmount} />
если у вас есть другая логика в didmount и unmount, создайте отдельные методы для обоих и привяжите NavigationEvents
Комментарии:
1. Спасибо вам! Это работает, хороший взлом. 🙂 Для чего используется ‘return true’ и что он делает?
2. если ничего не возвращено или возвращено false, будет запущена обычная функция кнопки возврата, а не та, которую вы закодировали в методе. Это полезно, если у вас есть условное поведение кнопки возврата.
3. В вашем решении есть одна проблема. Текущий компонент не отключается, когда я выполняю ‘this.props.navigation.navigate(‘SomeScreen’);’ , поэтому метод componentWillUnmount не выполняется. Это вызывает странное поведение, если я переключаюсь между разными экранами.
4. если, например, у меня есть экраны a, b, c и d. Навигация должна быть a-> b, b-> c, b-> d, b<-d, a<-c. Если я перейду на a, b и c, я вернусь к a (пока нормально), затем a-> b, b-> d, d-> b (пока нормально), но если я перейду на c, когда я вернусь, я вернусь к b вместоa. Потому что последний EventListener не был удален, а новый не добавлен.
5. У меня есть эта ошибка: Инвариантное нарушение: Инвариантное нарушение: недопустимый тип элемента: ожидал строку (для встроенных компонентов) или класс / функцию (для составных компонентов), но получил: объект. Проверьте метод визуализации
CtrlWelcome
.
Ответ №2:
Я нашел решение. Вот мой код :
export default class App extends React.Component {
render() {
return <AppContainer />;
}
};
const stackMapPI = createStackNavigator({
Map: {
screen: CtrlMap,
navigationOptions: () => ({
header: null
})
},
PI: {
screen: MainCtrlPIQuizz,
navigationOptions: () => ({
header: null
})
}
});
const stackNav = createStackNavigator({
Welcome: {
screen: MainCtrlWelcome,
navigationOptions: () => ({
header: null
})
},
Option: {
screen: CtrlOptions,
navigationOptions: () => ({
header: null
})
},
Map: {
screen: stackMapPI,
navigationOptions: () => ({
header: null
})
}
});
const AppContainer = createAppContainer(stackNav);