I'm trying to learn the React / Redux and build the simple app by using .Net core Api as the backend service.
My Requirements
Add item when the user clicks Save button
Redirect to the List page and load the data again to retrieve the newly added data
I have to reload the data and cannot just append the new item in the list because I need to get the keyId of the newly added item which is just generated
So, I do the chaining of promises in my action file to call LoadItems after AddItem is successful.
If I don't chain these promises, I could not see the newly created item in the List page. The redirection to '/todo' occurs so quickly even before the AddItem() is not completed yet. If I added 2 seconds delay for the redirection, I could see the new item.
Actions
export const addTodoItemSuccess = todoItem => ({ type: actionTypes.ADD_TODO_ITEM_SUCCESS, payload: todoItem });
export const loadTodoItemsSuccess = items => ({ type: actionTypes.LOAD_TODO_SUCCESS, payload: items });
export const loadTodoItems = () => {
return function (dispatch) {
return TodoService.getAll().then(items => {
dispatch(loadTodoItemsSuccess(items));
});
};
}
export const addTodoItem = (item) => {
return function (dispatch) {
return TodoService.add(item).then(() => {
return TodoService.getAll().then(items => {
dispatch(loadTodoItemsSuccess(items));
});
});
};
}
Reducer
import * as actionTypes from '../actions/actionTypes';
const todoReducer = (state = [], action) => {
switch (action.type) {
case actionTypes.LOAD_TODO_SUCCESS:
return action.payload;
default:
return state;
}
}
export default todoReducer;
AddTodoPage Container
submitNewTodo = event => {
event.preventDefault();
this.props.addTodoItem(this.state.item);
//redirect to Todo List Page after saving
this.context.router.history.push(`/todo`);
}
TodoListPage Container
componentDidMount = () => {
this.props.dispatch(loadTodoItems());
}
It works as expected and I can see the new item in the list. But the problem is that it's sending TWO GetAll() queries to the Api.
First call comes from Actions.js and Second call comes from componentDidMount in TodoListPage.js.
If I removed the
loadTodoItems()from thecomponentDidMount, I could not view any items when I just navigate to TodoListPage '/todo' because the items are not loaded yet.
In tutorials, they usually do store.dispatch(loadTodoItems()); in index.js to make it available. I feel wrong to load the data even before the user hasn't navigated to that page (except lookup data).
Could you please suggest me what's the best way to achieve my requirements above? I don't want to call the Api twice to refresh the data.
The complete set of code can be found here: https://github.com/ttcg/react-redux-todo/tree/todocrud/src
