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
//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.