Below is my component class. The component never seems to execute componentWillUpdate(), even when I can see the state updating by logging before the return in mapStateToProps. The state is 100% changing, however the component doesn't refresh.
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { search } from './mapActions'
import L from 'leaflet'
class Map extends Component {
componentDidMount() {
L.Icon.Default.imagePath = './images'
this.map = new L.Map('map', {
center: new L.LatLng(this.props.lat, this.props.lng),
zoom: this.props.zoom,
layers: L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '<a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
})
})
}
componentWillUpdate() {
console.log('UPDATE MAP')
L.geoJson(this.props.data).addTo(this.map)
}
render() {
return <div id="map"></div>
}
}
const mapStateToProps = (state) => {
return {
isFetching: state.isFetching,
data: state.data
}
}
const mapDispatchToProps = (dispatch) => {
return {
search: (name) => {
dispatch(search(name))
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Map)
And here is the map reducer:
const initialState = {
isFetching: false,
data: {}
}
export const map = (state = initialState, action) => {
switch(action.type) {
case 'REQUEST_SEARCH_RESULTS':
return Object.assign({}, state, {
isFetching: true
})
case 'RECEIVE_SEARCH_RESULTS':
return Object.assign({}, state, {
isFetching: false,
data: action.data
})
default:
return state
}
}
After some more testing and logging it seems that when it goes to map state to props the state object it uses to map to props contains the correct data, so state.map.data is correct and I can see the return from the fetch. However when I then log this.props in componentWillUpdate(), the data object is there but empty.
Make sure you are listening to that store in your maps file if you are passing props to your component through maps file.
componentWillUpdate receives the incoming props as an argument. At this time,
this.props
is still the old props. Try changing your method like so:I had a similar problem to Marina, which I solved in a similar fashion. Hopefully this explanation helps someone.
I'm going to use a simple example with blog posts. In your reducer, you're probably doing something as follows:
Instead of that, you must do the following:
In the first example, you're not actually changing the object reference. Your new posts variable is a reference to your old posts variable.
Also, be careful when using the constructor of the component. That was my problem.
e.g.
I had a similar problem and I found out the answer after read this:
When I tried use
Object.assign({}, object)
as you, it didn't work anyway. So was when I found this:Then I understood that I had to do this:
JSON.parse(JSON.stringify(object))
or just this:
{...object}
For Arrays:
[...theArray]
I hope that this will help you