So I'm creating something like "Trello" clone with react redux nodejs and mongoDB and i have some issue. The problem is when I add a card to a list its not update the redux state, so I will see the card in the list only after a refresh page. (the card added to the DB but not to redux state).
just for more info: boardlists is an array inside the object board from mongo, inside that array there is objects of list, inside each of them there is an array of cards.
here is my code:
REDUCER
const initialState = {
boardLists: [
],
};
export default function (state = initialState, action) {
switch (action.type) {
case FETCH_ITEMS_BEGIN:
return {
...state,
loading: true,
errors: null,
};
case FETCH_ITEMS_SUCCESS:
return {
...state,
loading: false,
boardLists: action.payload.data.boardLists,
};
case FETCH_ITEMS_FAILURE:
return {
...state,
loading: false,
errors: action.payload.errors,
boardLists: [],
};
//handless creation of data
case ADD_LIST:
return {
boardLists: [...state.boardLists, action.payload.list],
};
case ADD_CARD:
return {
boardlists: [...state.boardlists, action.payload.card],
}
ACTIONS
export const fetchItemsBegin = () => ({
type: FETCH_ITEMS_BEGIN,
});
export const fetchItemsSuccess = (data) => ({
type: FETCH_ITEMS_SUCCESS,
payload: { data },
});
export const fetchItemsFailure = (errors) => ({
type: FETCH_ITEMS_FAILURE,
payload: { errors },
});
//dispatched when item needs to be created
export const addList = (list) => {
return {
type: ADD_LIST,
payload: { list },
};
};
// add card
export const addCard = (card) => {
return {
type: ADD_CARD,
payload: { card }
};
};
//dispatched when all the lists from board stored in redux store needs to be read
export const getBoardLists = () => {
return (dispatch) => {
// function starts
dispatch(fetchItemsBegin()); // fetching begins
return http
.get(`${myUrl}/boards/one`) // req data from server
.then(({ data }) => {
console.log(data);
// if data is found
dispatch(fetchItemsSuccess(data)); // success
})
.catch((error) => dispatch(fetchItemsFailure(error))); //errors
};
};
COMPONENT THAT HANDLE THE ADD FUNCTION
handleAddCard = () => {
//add card
const { text } = this.state;
const { listID } = this.props;
const newCard = {
// _id: uuidv4(),
text,
};
cardService.createCard(newCard, listID);
this.props.addCard(newCard);
};
.
.
.
.
.
const mapStateToProps = ({ boardLists, loading, errors }) => ({
boardLists,
loading,
errors,
});
export default connect(mapStateToProps, { addList, addCard, getBoardLists })(ActionButton);
It appears you need to update an object in your lists array, and not add the card item to the list array itself.
In the actions:
// add card
export const addCard = (card, listId) => {
return {
type: ADD_CARD,
payload: { listId, card }
};
};
In the Reducer, you will need to find the list with matching id and add the card to its array e.g.:
case ADD_CARD:
const {listId, card} = action.payload;
return {
...state,
boardLists: state.boardLists.map(list => {
list.cards = list.cards || [];
return list.id === listId ? {...list, cards: [...list.cards, card]} : list
}),
}
This other question on stack overflow could be useful for this part. link