无法读取undefined未定义的属性

[英]Cannot read property undefined of undefined


Current Behavior

I am very new to React and pretty much all this stack. What I am trying to accomplish is to implement a tab navigator inside a stack navigator. I've done this without Redux using React navigation library but I can not do it when I move my stack navigator to Redux. I've even tried a different navigation library and I keep ending up with that error in the title which is driving me crazy because it does not tell much (or I just do not get it).

我是React的新手,几乎所有这些堆栈。我想要完成的是在堆栈导航器中实现选项卡导航器。我使用React导航库在没有Redux的情况下完成了这个,但是当我将堆栈导航器移动到Redux时我无法做到这一点。我甚至尝试了一个不同的导航库,我一直在标题中结束这个错误,这让我发疯,因为它并没有说明多少(或者我只是没有得到它)​​。

I've used the exact Redux example available in the examples repo. everything works until I change my home screen (the one after login) to a tab navigator I've created.

我已经使用了示例repo中提供的Redux示例。一切正常,直到我将主屏幕(登录后的屏幕)更改为我创建的标签导航器。

main.js (expo project)

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;

helpers/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);

helpers/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);

Home tab reducer

主页标签减速机

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;

App navigation reducer

App导航减速机

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;

My Environment

"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"
}

I have no idea what I am doing wrong or if this is a bug (I bet that it is me though) and I could use some light.

我不知道我做错了什么,或者这是一个错误(我敢打赌,这是我),我可以使用一些光。

update 1

I've taken off redux from my child navigation (home screen tab nav) and now the error statement has changed to the one below.

我已从我的子导航(主屏幕选项卡导航)中删除了redux,现在错误语句已更改为下面的错误。

Warning: Failed prop type: The prop `dispatch` is marked as required in `HomeNavigationTab`, but its value is `undefined`.

1 个解决方案

#1


0  

Based on the TabNavigator example here you don't actually need to pass in dispatch or nav in the to your component. So remove them and export (or export default)HomeNavigator instead.

根据TabNavigator示例,您实际上不需要将调度或导航传递到组件中。因此,删除它们并导出(或导出默认值)HomeNavigator。

import React from 'react';
import PropTypes from 'prop-types';
import { 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, 
  } 
});

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2017/06/18/a332c4cb8875cada1b06e94d246cb196.html



 
  © 2014-2022 ITdaan.com 联系我们: