Reputation: 566
I had a problem in component re-rendering even props are changed. I had a reducer(below) which handles the state of a photo album and uploading of any new photo in that.
const profilePhotoReducer = (state={
fetching: false,
photos: [],
dataSetChanged: false,
uploading: false
},action)=>{
console.log('reducer called: ', action.type);
switch (action.type){
case "PHOTOS_FETCHING":
return{
...state,
fetching: true
};
case "PHOTOS_FETCH_SUCCESS":
return {
...state,
fetching: false,
photos: action.payload,
dataSetChanged: false
};
case "PHOTOS_FETCH_FAILED":
return {
...state,
fetching: false,
dataSetChanged: false
};
case "UPLOADING":
return {
...state,
uploading: true
};
case "UPLOAD_SUCCESS":
return {
...state,
dataSetChanged: true,
uploading: false
};
case "UPLOAD_FAILED":
return {
...state,
uploading: false
};
default:
return state;
}
};
export default profilePhotoReducer;
after the successful photo upload the 'UPLOAD_SUCCESS' action.type is matched and flips the dataSetChanged(Boolean) and in my component(below) I'm handling it this way:
class ProfilePhotosComponent extends React.Component{
componentDidMount(){
console.log('********------***********: ', this.props.profilePhoto.dataSetChanged);
if(this.props.profilePhoto.photos.length === 0 || this.props.profilePhoto.dataSetChanged){
this.props.getPhotos();
}
}
render(){
const PhotoList = this.props.profilePhoto.photos.map((photo, i)=>{
return (<PhotoComponent name={photo} key={i}/>);
});
return (
<div className={'card pcard'}>
<div className={'col-md-12'}>
<UploadPhotoForm handleUpload={this.props.handleUpload}/>
{PhotoList}
</div>
</div>
);
}
}
function mapStateToProps(state){
return {
profilePhoto: state.profilePhoto
};
}
function mapDispatchToProps(dispatch){
return bindActionCreators({
getPhotos,
handleUpload
},dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(ProfilePhotosComponent);
Upvotes: 0
Views: 579
Reputation: 281666
The thing is that componentDidMount
function is called only once after component has mounted, after that if the props change, your component is re-rendered but your photos are not fetched again and hence you don't see a difference, what you need is componentWillReceiveProps
componentWillReceiveProps(nextProps) {
console.log('********------***********: ', nextProps.profilePhoto.dataSetChanged);
if(this.props.profilePhoto.dataSetChanged !== nextProps.profilePhoto.dataSetChanged) {
if(nextProps.profilePhoto.photos.length === 0 || nextProps.profilePhoto.dataSetChanged){
this.props.getPhotos();
}
}
}
Upvotes: 1
Reputation: 8066
In your mapStateToProps
I don't see that you have dataSetChanged
returned like this.
function mapStateToProps(state){
return {
dataSetChanged: state. dataSetChanged
};
}
And ComponentDidMount will not get called when props are updated, You have to either use componentWillReceiveProps()
or directly bind that property to a JSX element in your render
function.
Upvotes: 0