How To Update Component On State Change In Redux
I am trying to update component on state change in redux. I have a list of images, when user deletes the image the component should update after deleting the targeted image.
I have tried using componentWillReceiveProps and componentDidUpdate life cycle method, but none is working here. Can someone please suggest me what I am doing wrong here?
what I have done so far
action
import { DELETE_GALLERY_SUCCESS, DELETE_GALLERY_FAIL} from "./types";
export const deleteGalleryImage = (id) => (dispatch, getState) => {
axios
.delete(`${baseURL}/api/aws/gallery/${id}/delete/`, tokenConfig(getState))
.then(res => {
dispatch({
type: DELETE_GALLERY_SUCCESS,
payload: res.data
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
dispatch({
type: DELETE_GALLERY_FAIL
});
});
};
types.js
export const DELETE_GALLERY_SUCCESS = "DELETE_GALLERY_SUCCESS"
export const DELETE_GALLERY_FAIL = "DELETE_GALLERY_FAIL"
Reducer
import {DELETE_GALLERY_SUCCESS, DELETE_GALLERY_FAIL} from "../actions/types";
const initialState = {
paginations: true,
isLoading: false,
gallery: [],
};
export default function (state = initialState, action) {
switch (action.type) {
case DELETE_GALLERY_SUCCESS:
return {
...state,
isLoading: false,
gallery: state.gallery.filter(gallery => gallery.id !== action.payload)
};
case DELETE_GALLERY_FAIL:
return {
...state,
isLoading: false
};
default:
return state;
}
}
Here is my component
import { getAllGalleryImages, deleteGalleryImage } from '../settings/../../actions/gallery';
class DeleteGalleryImage extends Component {
componentDidMount() {
this.props.getAllGalleryImages();
}
componentWillReceiveProps(nextProps) {
if (this.props.images !== nextProps.images) {
// This is not working.
// what life cycle method should I use for this scenario?
//this.props.getAllGalleryImages()
}
}
handleDelete = (id) => {
this.props.deleteGalleryImage(id)
}
render() {
return (
<Row>
<Col xs={24} sm={22} offset={1}>
<h1 className='sub-page-heading'><span className='common_dlt'>Delete</span> Gallery Image</h1>
<div className='masonry'>
{this.props.images && this.props.images.results && this.props.images.results.map(result =>
<div className='masonry-item' key={result.id}>
<img src={result.gallery_img_url} className='dlt_blg_img' alt='img' id={result.id} />
<span className='gallery_delete_zone' onClick={() => this.handleDelete(result.id)}><Icon type="delete" /></span>
</div>
)}
</div>
</Col>
</Row>
)
}
}
const mapStateToProps = state => ({
images: state.gallery
});
export default connect(
mapStateToProps,
{ getAllGalleryImages, deleteGalleryImage }
)(DeleteGalleryImage);
Store
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
rootReducer
import { combineReducers } from "redux";
import gallery from './gallery';
export default combineReducers({
gallery,
});
Answer
In this case no need to use componentWillReceiveProps, If you can change the store succcesfully the component will be rendered automatically since it is connected to the store.
Another thing I noticed is in your deleteGalleryImage action, I think you need to send id input parameter as payload, because we cannot assume if res.data will be id.
dispatch({
type: DELETE_GALLERY_SUCCESS,
payload: id
})
Edit: based on the info I got from comments, I understood your initial state
const initialState = {
count: 2,
gallery: {},
isLoading: true,
next: null,
paginations: true,
previous: null,
results: [{}, {}]
};
So your DELETE_GALLERY_SUCCCESS case must be like this if you want to remove a image in results array.
case DELETE_GALLERY_SUCCESS:
return {
...state,
isLoading: false,
results: state.results.filter(image => image.id !== action.payload)
}
};
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?