Текущее поведение
Я новичок в React и почти во всем этом стеке. Я пытаюсь реализовать навигатор вкладок внутри навигатора стека. Я сделал это без Redux, используя библиотеку навигации React, но я не могу это сделать, когда я двигаюсь мой навигатор по стеку в Redux. Я даже пробовал другую библиотеку навигации, и у меня все время появляется ошибка в заголовке, которая сводит меня с ума, потому что она мало что говорит (или я ее просто не понимаю).
Я использовал точный пример Redux, доступный в репозитории примеров. все работает до тех пор, пока я не изменю свой домашний экран (тот, который после входа в систему) на созданный мной навигатор вкладок.
main.js (выставочный проект)
import Expo from 'expo';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux';
import store from './store';
import AppWithNavigationState from './helpers/AppNavigator';
class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppWithNavigationState />
</Provider>
);
}
}
Expo.registerRootComponent(App);
store.js
import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import { AsyncStorage } from 'react-native';
import reducers from '../reducers';
const store = createStore(
reducers,
{},
compose(
applyMiddleware(thunk),
autoRehydrate()
)
);
// persistStore(store, { storage: AsyncStorage, whitelist: ['likedJobs'] });
export default store;
помощники / AppNavigator.js
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
import LoginScreen from '../screens/auth/LoginScreen';
// import HomeScreen from '../screens/HomeScreen';
// import HomeRoutes from '../routes/HomeRoutes';
import HomeRoutes from '../helpers/HomeNavigator';
export const AppNavigator = StackNavigator({
Login: { screen: LoginScreen },
Home: { screen: HomeRoutes },
});
const AppWithNavigationState = ({ dispatch, nav }) => (
<AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })} />
);
AppWithNavigationState.propTypes = {
dispatch: PropTypes.func.isRequired,
nav: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
nav: state.nav,
});
export default connect(mapStateToProps)(AppWithNavigationState);
помощники / homeNavigator
import React from 'react';
import PropTypes from 'prop-types';
// import { connect } from 'react-redux';
import { addNavigationHelpers, TabNavigator } from 'react-navigation';
import CustomerListScreen from '../screens/home/CustomerListScreen';
import JobListScreen from '../screens/home/JobListScreen';
JobListScreen.navigationOptions = {
tabBarLabel: 'Jobs',
title: "Jobs",
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name='wrench'
size={24}
style={{ color: tintColor }}
/>
),
};
CustomerListScreen.navigationOptions = {
tabBarLabel: 'Clients',
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name='users'
size={24}
style={{ color: tintColor }}
/>
),
};
export const HomeNavigator = TabNavigator({
Jobs: {
screen: JobListScreen,
},
Clients: {
screen: CustomerListScreen,
}
});
const HomeNavigationTab = ({ dispatch, nav }) => (
<HomeNavigator navigation={addNavigationHelpers({ dispatch, state: nav })} />
);
HomeNavigationTab.propTypes = {
dispatch: PropTypes.func.isRequired,
nav: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
homeNav: state.nav,
});
export default HomeNavigationTab;
// export default connect(mapStateToProps)(HomeNavigationTab);
Редуктор вкладки домашней страницы
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
import { HomeNavigator } from '../helpers/HomeNavigator';
// Start with two routes: The Main screen, with the Login screen on top.
const firstAction = HomeNavigator.router.getActionForPathAndParams('Jobs');
const tempNavState = HomeNavigator.router.getStateForAction(firstAction);
const secondAction = HomeNavigator.router.getActionForPathAndParams('Clients');
const initialNavState = HomeNavigator.router.getStateForAction(
secondAction,
tempNavState
);
function homeTabNav(state = initialNavState, action) {
let nextState;
switch (action.type) {
case 'JOBS':
nextState = HomeNavigator.router.getStateForAction(
NavigationActions.navigate({ routeName: 'Jobs' }),
state
);
break;
case 'CLIENTS':
nextState = HomeNavigator.router.getStateForAction(
NavigationActions.navigate({ routeName: 'Clients' }),
state
);
break;
default:
nextState = HomeNavigator.router.getStateForAction(action, state);
break;
}
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
}
export default homeTabNav;
Редуктор навигации приложений
import { combineReducers } from 'redux';
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
import { AppNavigator } from '../helpers/AppNavigator';
// Start with two routes: The Main screen, with the Login screen on top.
const firstAction = AppNavigator.router.getActionForPathAndParams('Home');
const tempNavState = AppNavigator.router.getStateForAction(firstAction);
const secondAction = AppNavigator.router.getActionForPathAndParams('Login');
const initialNavState = AppNavigator.router.getStateForAction(
secondAction,
tempNavState
);
function nav(state = initialNavState, action) {
let nextState;
switch (action.type) {
case 'NAV_LOGIN_SUCCESS':
nextState = AppNavigator.router.getStateForAction(
NavigationActions.back(),
state
);
break;
case 'LOGOUT':
nextState = AppNavigator.router.getStateForAction(
NavigationActions.navigate({ routeName: 'Login' }),
state
);
break;
default:
nextState = AppNavigator.router.getStateForAction(action, state);
break;
}
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
}
export default nav;
Моя среда
"dependencies": {
"axios": "^0.16.2",
"expo": "17.0.0",
"native-base": "^2.1.5",
"react": "16.0.0-alpha.6",
"react-native": "https://github.com/expo/react-native/archive/sdk-17.0.0.tar.gz",
"react-native-easy-grid": "^0.1.13",
"react-native-vector-icons": "^4.2.0",
"react-navigation": "^1.0.0-beta.11",
"react-redux": "^5.0.5",
"redux": "^3.7.0",
"redux-persist": "^4.8.0",
"redux-thunk": "^2.2.0"
}
Я понятия не имею, что я делаю не так, или это ошибка (держу пари, что это я), и я мог бы использовать немного света.
обновление 1
Я снял сокращение с моей дочерней навигации (вкладка на главном экране), и теперь сообщение об ошибке изменилось на приведенное ниже.
Warning: Failed prop type: The prop `dispatch` is marked as required in `HomeNavigationTab`, but its value is `undefined`.
HomeScreen
файл? Судя по вашему описанию, скорее всего, в этом и заключается проблема. Кроме того, выдает ли ошибка имя файла и номер строки? - person DonovanM   schedule 18.06.2017cannot read property undefined of undefined
, это означает, что вы пытаетесь прочитать свойство неопределенного объекта. Причина, по которой это может произойти, заключается в том, что редукторы запускаются один раз перед засеиванием состояния, которое вы планируете визуализировать. Если вы не определите какое-то начальное состояние, вы можете получить такую ошибку. Как выглядят ваши редукторы? - person whs.bsmith   schedule 18.06.2017