简体   繁体   中英

Setting up Redux with React Native function undefined

I think I'm close with setting up React Redux for my React native app. I currently have this set up.

Here I define the action that I want to call.

 /* actions/mapActions.js */ export const setMarker = selectedMarker => { return { type: 'SET_MARKER', selectedMarker } } 

Here I define the container for the component that I want to use the store in.

 //containers/mapContainers.js import { connect } from 'react-redux'; import { setMarker } from './actions/mapActions' import HomeScreen from './screens/HomeScreen' const mapStateToProps = state => { return { selectedMarker: state.marker } } const mapDispatchToProps = dispatch => { return { markerClick: (marker) => { dispatch(setMarker(marker)) } } } export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen) 

Here I combine the reducers as I've seen in a tutorial I've been following.

 //reducers/index.js import { combineReducers } from 'redux' import mapReducer from './mapReducer' const dabApp = combineReducers({ mapReducer }) export default dabApp 

Here I define the reducer for the component.

 //reducers/mapReducers.js const mapReducer = (state = [], action) => { switch (action.type) { case 'SET_MARKER': return [ ...state, { marker: action.marker } ] default: return state } } export default mapReducer 
Main entry point to the application.
 //App.js // other imports here import { Provider } from 'react-redux'; import { createStore } from 'redux'; import snapApp from './reducers'; let store = createStore(dabApp); export default class App extends React.Component { state = { isLoadingComplete: false, }; render() { return ( <Provider store={store}> <View style={styles.container}> {Platform.OS === 'ios' && <StatusBar barStyle="default" />} {Platform.OS === 'android' && <View style={styles.statusBarUnderlay} />} <RootNavigation /> </View> </Provider> ); } } const styles = StyleSheet.create({ //Styles. }); 

Here I define the component.

 //Standard react imports. import { MapView } from 'expo'; import { connect } from 'react-redux'; export default class HomeScreen extends React.Component { constructor(props) { super(props); this.state = { //Set states. }; } render() { return ( <View style={styles.container}> <MapView //MapView info > {this.state.markers.map((marker) => <MapView.Marker key={marker.id} coordinate={marker.coordinate} onPress={() => {this.props.markerClick(marker); this.props.navigation.navigate('Information');}}> </MapView.Marker> )} </MapView> </View> ); } } const styles = StyleSheet.create({ //Styles. }); 

The error I get is that the function 'markerClick' is undefined in the Map.Marker onPress prop. I have followed the tutorial religiously and can't find the solution to this.

The tutorial that I was following was this one on the official redux site. http://redux.js.org/docs/basics/ExampleTodoList.html .

Has anyone encountered the same issue?

Unfortunately, Harry's answer hasn't solved the issue.

I console.log(this.props) and I get this:

Still is undefined. When I console.log(this.props") I get:

  Object { "navigation": Object { "dispatch": [Function anonymous], "goBack": [Function goBack], "navigate": [Function navigate], "setParams": [Function setParams], "state": Object { "key": "Home", "routeName": "Home", }, }, "screenProps": undefined, "selectedMarker": [Function dispatch], "type": "SET_MARKER", } 

so I don't even see the function on my props.

As you can see, the function is not defined on this.props.

Thanks,

I feel like you're making more steps than needed.

Try something like this:

import React, { Component } from 'react';
import { MapView } from 'expo';
import { connect } from 'react-redux';
import { View, StyleSheet } from 'react-native';
import { setMarker } from './actions/mapActions'


class HomeScreen extends Component {
  onPress(marker) {
    this.props.setMarker(marker);
    this.props.navigation.navigate('Information');
  }

  render() {
    return (
      <View style={styles.container}>
         <MapView>
           {this.state.markers.map((marker) => (
             <MapView.Marker
               key={marker.id}
               coordinate={marker.coordinate}
               onPress={() => { this.onPress(marker); }}
             />
           )
        )}
      </MapView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  //Styles.
});

export default connect(null, setMarker)(HomeScreen);

You don't need to define a function that then dispatches an action, you can just connect the action to the component. It's also much nicer to just have everything in the same file instead of having a separate mapContainers.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM