I try to render items that are in my firestore database. It displays correctly on the first render but when I switch between tabs/navigations it will readd the data to the list again. If I keep on switching between the tabs it will add more and more.
When I use local state there is no issue with that but the issue is with when I use dispatch to display items it will readd more items to the list(not the firestore database).
useEffect(
() =>
onSnapshot(collection(db, "users"), (snapshot) => {
console.log(
"snapshot",
snapshot.docs.map((doc) => doc.data())
);
const firebaseData = snapshot.docs.map((doc) => doc.data());
dispatch(addItem(firebaseData));
setLocalState(firebaseData);
}),
[]
);
itemsSlice.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
items: [],
};
const itemsSlice = createSlice({
name: "addItems",
initialState,
reducers: {
addItem: (state, action) => {
state.items.push(...action.payload);
},
emptyItems: (state) => {
state.items = [];
},
},
});
export const { addItem, emptyItems } = itemsSlice.actions;
export default itemsSlice.reducer;
Here is a gif of the issue: https://gyazo.com/bf033f2362d9d38e9eb315845971e224
CodePudding user response:
Since I don't understand how you're switching between tabs, I can't tell you why the component seems to be rerendering. The useEffect
hook is responsible to act like both the componentDidMount
and componentDidUpdate
methods. And the global redux state is not going to reset itself after each render (which is why it's so great).
This is not the case for a component's state which well reset each time a component is removed from and added to the dom. This explains why when you use a local state, the problem disappears. It's not that its fixed, it's because the state is reset every time the component is removed and added (which is what seems to be happening here).
Since we don't have the full details a quick fix should be to replace this
state.items.push(...action.payload);
with this
state.items = [...action.payload];
this will set a new value to state.items
instead of pushing to it.