#reactjs #react-native #react-redux #firebase-authentication #react-navigation
#reactjs #react-native #реагировать-redux #firebase-аутентификация #react-навигация
Вопрос:
Мое приложение, основанное на react, использует react-redux и react-navigation.
App.js импортирует Main
компонент. Внутри Main
импортируется react-navigation и определяются все навигаторы. Тем не менее, я все еще получаю ошибку типа: неопределенный не является объектом (вычисление ‘that.navigation.navigate’)] на that.navigation.navigate('Auth')
в Main
.
Я также пробовал, navigation.navigate('Auth')
но не могу найти переменную: navigation. Является ли плохой практикой импортировать react-navigation и использовать его в одном файле? Я хотел бы использовать навигацию в, Main
чтобы избежать вызова firebase.auth().onAuthStateChanged
на каждом экране.
App.js
...
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
class App extends React.Component {
render() {
return (
<Provider store={store}>
<Main />
</Provider>
);
}
}
export default App;
Main.js
import React from 'react';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
...
const MainStack = createSwitchNavigator(
{
Home: HomeStack,
Auth: AuthStack
},
{
initialRouteName: 'Home'
}
);
const AppContainer = createAppContainer(MainStack);
class Main extends React.Component {
constructor(props) {
super(props);
}
componentDidMount = () => {
var that = this;
firebase.auth().onAuthStateChanged(async function(user) {
if (user) {
await that.props.getUserProfile(user.uid);
} else {
that.navigation.navigate('Auth');
}
})
}
render() {
return (
<AppContainer />
);
}
}
const mapStateToProps = state => {
return {
user: state.auth.user
}
}
export default connect(mapStateToProps, {getUserProfile})(Main);
Ответ №1:
У вас есть реквизиты.
Изменить that.navigation.navigate('Auth');
на that.props.navigation.navigate('Auth');
Комментарии:
1. Не работает; навигация в этом случае не передается из реквизитов
Ответ №2:
Я не уверен, потому что я никогда не использовал react navigation, но похоже, что только AppContainer и его дочерние элементы обернуты, а не основной компонент, поэтому навигация здесь не определена. Вам следует пересмотреть порядок архитектуры вашего компонента
Форма https://facebook.github.io/react-native/docs/navigation
Каждый компонент экрана может устанавливать параметры навигации, такие как заголовок заголовка. Он может использовать создателей действий в
navigation
реквизите для ссылки на другие экраны
Ваш Main
компонент не является экраном, вы не можете использовать навигацию в нем.
Вы можете сделать что-то подобное :
const AppContainer = isAuthentified => createAppContainer(createStackNavigator(
{
Home: HomeStack,
Auth: AuthStack
},
{initialRouteName: !!isAuthentified ? 'Home' : 'Auth'}
));
class Main extends React.Component {
constructor(props) {
super(props);
state = {loading: false};
}
componentDidMount = () => {
let tmpuser = false;
firebase.auth().onAuthStateChanged(async function(user) {
if (user) {
tmpuser = await that.props.getUserProfile(user.uid);
}});
this.setState({user: tmpuser, loading: false})
}
render() {
if (!this.state.loading)
return (
<div>{AppContainer(this.state.user)}</div>
);
else return (<div>loading</div>);
}
}
// Может быть не идеальным, сделано на смартфоне
Комментарии:
1. Да, я мог бы вызвать
firebase.auth().onAuthStateChanged
на одном из моих экранов в домашнем стеке, но тогда он вызывается каждый раз, когда я перехожу к новому экрану. ПричинаMain
здесь заключается в том, чтобы вызвать функцию только один раз2. MainStack — это switch navigator, не уверен, как вы планируете это делать там?
3. Я не думаю, что вы говорите об одном и том же, мне нужно куда-то позвонить
firebase.auth().onAuthStateChanged
, это невозможно сделать в MainStack, потому что это просто навигатор4. Можете ли вы указать это в своем ответе, это трудно понять