1

我正在使用react native 关闭画布菜单和 redux。

我现在需要以编程方式导航,我认为在画布菜单之外做出原生反应是不允许的,所以我需要引入我能找到的最简单的导航系统来添加到我的应用程序中。

我正在尝试添加react native redux 路由器,但出现错误:

Connect(Router) 中的 mapStateToProps() 必须返回一个普通对象。而是收到未定义的。

代码:

这真的是我的基本组件。它仅用于包含<Menu/>,但我添加了一个Router

Vepo.js

import React, { Component } from 'react'
import { fetchCategories } from './categories/categories.action'
import { getCurrentPosition } from './location/location.action'
import Menu from './menu/Menu'
import { View } from 'react-native'

import AddPage from './add-page/AddPage'
import SearchPage from './search-page/SearchPage'



var { Router, Route } = require('react-native-redux-router')

class Vepo extends Component {
  componentDidMount() {
    const { store } = this.context
    this.unsubscribe = store.subscribe(() => { })
    store.dispatch(getCurrentPosition())
    store.dispatch(fetchCategories())
  }

  componentWillUnmount() {
    this.unsubscribe()
  }

  render() {
    console.log('vepo')
    return (
      <View>
        <Menu />
        <Router>
          <Route name="add" component={AddPage} />
          <Route name="search" component={SearchPage} />
        </Router>
      </View>
    )
  }
}
Vepo.contextTypes = {
  store: React.PropTypes.object
}

export default Vepo

并在这里创建:

index.js

//@flow
import { createStore, applyMiddleware } from 'redux'
import { combineReducers } from 'redux-immutable'
import { Provider } from 'react-redux'
import Vepo from './components/Vepo'
import keyword from './components/search-page/keywords.reducer'
import categories from './components/categories/categories.reducer'
import { location } from './components/location/location.reducer'
import distanceFromPlaceValue from
  './components/distanceSlider/distanceSlider.reducer'
import searchPage from './components/search-page/searchPage.reducer'
import {
  fetchProductsEpic,
  fetchProductsFulfilledEpic
} from './components/search-page/searchPage.epic'
import addPage from './components/add-page/addPage.reducer'
import productDetails from './components/add-page/addForm.reducer'
import alertModal from './components/alert-modal/alertModal.reducer'
import map from './components/map/map.reducer'
import menu from './components/menu/menu.reducer'
import initialState from './config/config'
import { composeWithDevTools } from 'remote-redux-devtools'
import React from 'react'
import { createEpicMiddleware, combineEpics } from 'redux-observable'
import fetchCategoriesEpic from './components/categories/categories.epic'
import {
  getCurrentLocationEpic,
  getCurrentPositionEpic,
  getAutocompleteResultsEpic,
  getPlaceDetailsEpic
} from './components/location/location.epic'
import {
  getShopAutocompleteResultsEpic,
  getShopPlaceDetailsEpic
} from './components/shop/shop.epic'
import {
  uploadImageEpic,
  uploadProductEpic,
  uploadImageFulfilledEpic,
  uploadImageRejectedEpic,
  uploadProductFulfilledEpic,
  uploadProductRejectedEpic
} from './components/add-page/addForm.epic'
import { shop } from './components/shop/shop.reducer'
import searchResults from './components/search-results/searchResults.reducer'
import searchResultsPresenter from './components/search-results/searchResultsPresenter.reducer'

const rootReducer = combineReducers(
  {
    searchForm: combineReducers(
      {
        keyword,
        categories,
        location,
        distanceFromPlaceValue
      }),
    searchPage,
    addPage,
    addForm: combineReducers({
      productDetails,
      shop
    }),
    map,
    searchResults,
    searchResultsPresenter,
    menu,
    alertModal,
  }
)

export const rootEpic = combineEpics(
  fetchCategoriesEpic,
  uploadImageEpic,
  uploadProductEpic,
  uploadImageFulfilledEpic,
  uploadImageRejectedEpic,
  getCurrentLocationEpic,
  fetchProductsFulfilledEpic,
  getCurrentPositionEpic,
  getShopAutocompleteResultsEpic,
  getShopPlaceDetailsEpic,
  getAutocompleteResultsEpic,
  fetchProductsEpic,
  getPlaceDetailsEpic,
  uploadProductFulfilledEpic,
  uploadProductRejectedEpic
)

export const store = createStore(
  rootReducer,
  initialState,
  composeWithDevTools(
    applyMiddleware(createEpicMiddleware(rootEpic))
  )
)

export const App = () => (
  <Provider store={store}>
    <Vepo />
  </Provider>
)

这是我想以编程方式导航的组件(搜索Actions.add()):

菜单.js

import React from 'react'
import { View } from 'react-native'
import Icon from 'react-native-vector-icons/EvilIcons'
import { connect } from 'react-redux'
import { closePageMenu, openPageMenu } from './menu.action'
import { OffCanvasReveal } from 'react-native-off-canvas-menu'
import AddPage from '../add-page/AddPage'
import SearchPage from '../search-page/SearchPage'
import AlertModal  from '../alert-modal/AlertModal'
import {
  updateAlertModalIsOpen
} from '../alert-modal/alertModal.action'
var { Actions } = require('react-native-redux-router')

const mapStateToProps = (state) => ({
  isOpen: state.get('menu').get('isOpen')
})

const mapDispatchToProps = (dispatch) => ({
  updateAlertModalIsOpen: (isOpen) => {
    dispatch(updateAlertModalIsOpen(isOpen))
  },
  closePageMenu: () => {
    console.log("you must have closed the menu")
    dispatch(closePageMenu())
  },
  openPageMenu: () => {
    console.log("you must have opened the menu")
    dispatch(openPageMenu())
  }
})

let Menu = (props) => {
  console.log('menu')
  return(
  <View style={{ flex: 1 }}>

    <AlertModal yesClicked={() => {
      Actions.add()
      console.log("yes clicked")
      props.updateAlertModalIsOpen(false)
    }} />
    <OffCanvasReveal
      active={props.isOpen}
      onMenuPress={props.closePageMenu}
      backgroundColor={'#222222'}
      menuTextStyles={{ 
        color: '#FFFFFF', backgroundColor: 'transparent'
      }}
      handleBackPress={true}
      menuItems={[
        {
          title: 'Search Products',
          icon: <Icon 
            name="search" 
            size={35} 
            color={'#FFFFFF'} />,
          renderScene: <SearchPage />
        },
        {
          title: 'Add Products',
          icon: <Icon 
            name="plus" 
            size={35}
            color={'#FFFFFF'} />,
          renderScene: <AddPage rerenderKey={false} />
        }
      ]} />
  </View>
)}
Menu.propTypes = {
  closePageMenu: React.PropTypes.func.isRequired,
  isOpen: React.PropTypes.bool.isRequired,
  updateAlertModalIsOpen: React.PropTypes.func
}

Menu = connect(
  mapStateToProps,
  mapDispatchToProps
)(Menu)

export default Menu

为什么我会收到错误消息?考虑到我在画布菜单外使用 react native,是否有更简单的导航方式?

编辑。刚刚添加了routerReducer:

var { routerReducer } = require('react-native-redux-router')

const rootReducer = combineReducers(
  {
    searchForm: combineReducers(
      {
        keyword,
        categories,
        location,
        distanceFromPlaceValue
      }),
    searchPage,
    addPage,
    addForm: combineReducers({
      productDetails,
      shop
    }),
    map,
    searchResults,
    searchResultsPresenter,
    menu,
    alertModal,
    routerReducer
  }
)

得到错误相同的错误

编辑:我现在正在尝试使用 react-navigation

index.js

//@flow
import { createStore, applyMiddleware } from 'redux'
import { combineReducers } from 'redux-immutable'
import { Provider, connect } from 'react-redux'
import Vepo from './components/Vepo'
import keyword from './components/search-page/keywords.reducer'
import categories from './components/categories/categories.reducer'
import { location } from './components/location/location.reducer'
import distanceFromPlaceValue from
  './components/distanceSlider/distanceSlider.reducer'
import searchPage from './components/search-page/searchPage.reducer'
import {
  fetchProductsEpic,
  fetchProductsFulfilledEpic
} from './components/search-page/searchPage.epic'
import addPage from './components/add-page/addPage.reducer'
import productDetails from './components/add-page/addForm.reducer'
import alertModal from './components/alert-modal/alertModal.reducer'
import map from './components/map/map.reducer'
import menu from './components/menu/menu.reducer'
import initialState from './config/config'
import { composeWithDevTools } from 'remote-redux-devtools'
import React, { Component } from 'react'
import { createEpicMiddleware, combineEpics } from 'redux-observable'
import fetchCategoriesEpic from './components/categories/categories.epic'
import {
  getCurrentLocationEpic,
  getCurrentPositionEpic,
  getAutocompleteResultsEpic,
  getPlaceDetailsEpic
} from './components/location/location.epic'
import {
  getShopAutocompleteResultsEpic,
  getShopPlaceDetailsEpic
} from './components/shop/shop.epic'
import {
  uploadImageEpic,
  uploadProductEpic,
  uploadImageFulfilledEpic,
  uploadImageRejectedEpic,
  uploadProductFulfilledEpic,
  uploadProductRejectedEpic
} from './components/add-page/addForm.epic'
import { shop } from './components/shop/shop.reducer'
import searchResults from './components/search-results/searchResults.reducer'
import searchResultsPresenter from './components/search-results/searchResultsPresenter.reducer'
import { StackNavigator, addNavigationHelpers } from 'react-navigation'

import AddPage from './components/add-page/AddPage'
import SearchPage from './components/search-page/SearchPage'

const AppNavigator = StackNavigator({
    Add: { screen: AddPage },
    Search: { screen: SearchPage }
})

const navReducer = (state, action) => {
    const newState = AppNavigator.router.getStateForAction(action, state)
    return newState || state
}

class AppWithNavigationState extends Component {
    render() {
        return (
            <AppNavigator
                navigation={addNavigationHelpers({
                    dispatch: this.props.dispatch,
                    state: this.props.nav
                })}
            />
        )
    }
}

let AppWithNavigationStateComponent = connect(state => ({
    nav: state.nav
}))(AppWithNavigationState)

export const App = () => {
    return (
        <Provider store={store}>
            <AppWithNavigationStateComponent />
        </Provider>
    )
}

const rootReducer = combineReducers(
  {
    searchForm: combineReducers(
      {
        keyword,
        categories,
        location,
        distanceFromPlaceValue
      }),
    searchPage,
    addPage,
    addForm: combineReducers({
      productDetails,
      shop
    }),
    map,
    searchResults,
    searchResultsPresenter,
    menu,
    alertModal,
    navReducer
  }
)

export const rootEpic = combineEpics(
  fetchCategoriesEpic,
  uploadImageEpic,
  uploadProductEpic,
  uploadImageFulfilledEpic,
  uploadImageRejectedEpic,
  getCurrentLocationEpic,
  fetchProductsFulfilledEpic,
  getCurrentPositionEpic,
  getShopAutocompleteResultsEpic,
  getShopPlaceDetailsEpic,
  getAutocompleteResultsEpic,
  fetchProductsEpic,
  getPlaceDetailsEpic,
  uploadProductFulfilledEpic,
  uploadProductRejectedEpic
)

export const store = createStore(
  rootReducer,
  initialState,
  composeWithDevTools(
    applyMiddleware(createEpicMiddleware(rootEpic))
  )
)

得到错误:

undefined 不是对象(评估 this.props.navigation.state.index

4

0 回答 0