Reputation: 3760
I'm still kinda new in using Redux inside React Native components. I'm facing a problem which I cannot solve for days now. Namely, I'm trying to get my navigation data, ie. latitude. What I want to do is to attach it to the redux state and get its value every 2 seconds. So inside of my component I'm using setInterval which runs my redux flow every 2 sec. On the way back to react component I would expect to have this state rerendered every time, but this is not what's happening. I'm getting it only once. I fallowed the similar issues here and in all the problem was not returning new object from a reducer. But I guess this is not my case. THANK YOU IN ADVANCE! Here's my code:
MY COMPONENT GEOBATTERY:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ScrollView, View, Text } from 'react-native';
import { Button } from './Button';
import {
appStoped,
setCoordinates,
updateGeolocationArray,
} from '../actions';
class GeoBattery extends Component {
handleStart() {
const geolocationArray = [];
let geolocationCounter = 0;
this.geoLocationInterval = setInterval(() => {
navigator.geolocation.getCurrentPosition(
(position) => {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
console.log(latitude);
this.props.setCoordinates(latitude, longitude);
},
);
geolocationArray.push({ id: geolocationCounter++, latitude: this.props.latitude, longitude: this.props.longitude });
this.props.updateGeolocationArray(geolocationArray);
}, 1000);
}
handleStop() {
clearInterval(this.geoLocationInterval);
}
handleNewLatitudeItems() {
return this.props.geolocationArrayToMap.map(item => {
return <Text key={item.id}> {item.latitude} </Text>;
});
}
render() {
console.log(this.props.latitude); // here it does not rerender
const { buttonStyle, resultsStyle, resultContainer } = styles;
return (
<ScrollView style={buttonStyle}>
<Button onPress={() => this.handleStart()}>START</Button>
<Button onPress={() => this.handleStop()}>STOP</Button>
<View style={resultContainer}>
<View style={{ flex: 4 }}>
<Text style={resultsStyle}> Lat: </Text>
<Text style={{ fontSize: 12 }}> { this.handleNewLatitudeItems() } </Text>
</View>
</View>
</ScrollView>
);
}
}
const styles = {
buttonStyle: {
marginTop: 20,
marginBottom: 20,
},
resultContainer: {
display: 'flex',
flexDirection: 'row',
},
resultsStyle: {
flex: 3,
fontSize: 15,
marginTop: 10,
textAlign: 'center'
}
};
const mapStateToProps = state => {
console.log(state.update.geolocationArrayToMap); //here it return what I need to map and dynamically create new list items of latitude
return {
latitude: state.coords.latitude,
geolocationArrayToMap: state.update.geolocationArrayToMap,
};
};
export default connect(mapStateToProps, { appStoped, setCoordinates, updateGeolocationArray })(GeoBattery);
MY ACTIONS:
import {
CLEAR_DATA,
SET_COORDS,
UPDATE_GEOLOCATION_ARRAY,
} from './types';
export const appStoped = () => {
return {
type: CLEAR_DATA
};
};
export const setCoordinates = (latitude, longitude) => {
return {
type: SET_COORDS,
payload1: latitude,
payload2: longitude
};
};
export const updateGeolocationArray = (geolocationArray) => {
return {
type: UPDATE_GEOLOCATION_ARRAY,
payload: geolocationArray
};
};
TYPES:
export const CLEAR_DATA = 'clear_data';
export const SET_COORDS = 'set_coords';
export const UPDATE_GEOLOCATION_ARRAY = 'update_geolocation_array';
MY INDEX REDUCER:
import { combineReducers } from 'redux';
import CoordsReducer from './CoordsReducer';
import UpdateReducer from './UpdateReducer';
export default combineReducers({
coords: CoordsReducer,
update: UpdateReducer,
});
MY COORDSREDUCER:
import { SET_COORDS, CLEAR_DATA } from '../actions/types';
const INITIAL_STATE = {
latitude: '',
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case SET_COORDS:
return { ...state, latitude: action.payload1 };
case CLEAR_DATA:
return { ...state, ...INITIAL_STATE };
default:
return state;
}
};
MY UPDATEREDUCER:
import { UPDATE_GEOLOCATION_ARRAY, CLEAR_DATA } from '../actions/types';
const INITIAL_STATE = {
geolocationArrayToMap: [],
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case UPDATE_GEOLOCATION_ARRAY:
return { ...state, geolocationArrayToMap: action.payload };
case CLEAR_DATA:
return { ...state, ...INITIAL_STATE };
default:
return state;
}
};
MYSTORE:
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import reducers from './reducers';
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
export default store;
Upvotes: 0
Views: 536
Reputation: 4464
Your are mutating the array you send to your action :
geolocationArray.push({ id: geolocationCounter++, latitude: this.props.latitude, longitude: this.props.longitude });
this.props.updateGeolocationArray(geolocationArray);
Try using an immutable way to do it :
this.props.updateGeolocationArray([...geolocationArray, { id: geolocationCounter++, latitude: this.props.latitude, longitude: this.props.longitude }]);
Upvotes: 2