'React and Firebase item counter
I am working on a small project that allows the user to enter an item in the input field and then increase/decrease the amount. All the data is stored in firebase. When there are multiple items, the count value of the previous item seems to overwrite the current item count when increasing/decreasing the values and therefore the values are not updated accurately. I think this has something to do with the way my count state is set up? Any insight would be appreciated!
import "./App.css";
import firebase from "./firebase";
import { getDatabase, ref, push, set, onValue } from "firebase/database";
import { useEffect, useState } from "react";
import Form from "./Form";
import GroceryItem from "./GroceryItem";
function App() {
const [groceryItems, setGroceryItems] = useState([]);
const [userInput, setUserInput] = useState("");
let [count, setCount] = useState(1);
useEffect(() => {
const database = getDatabase(firebase);
const dbRef = ref(database);
onValue(dbRef, (response) => {
const dbData = response.val();
const dataArray = [];
for (let key in dbData) {
dataArray.push({
key: key,
itemName: dbData[key].itemName,
amount: dbData[key].amount,
apiImage: dbData[key].apiImage,
});
}
setGroceryItems(dataArray);
});
}, []);
const handleUserInput = (event) => {
setUserInput(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
if (!userInput) {
alert("Please enter an item!");
} else {
const database = getDatabase(firebase);
const dbRef = ref(database);
push(dbRef, {
itemName: userInput,
amount: 1,
});
setUserInput("");
}
};
const handleIncreaseAmount = (key) => {
const database = getDatabase(firebase);
const dbRef = ref(database, `/${key}/amount`);
setCount((count += 1));
set(dbRef, count);
};
const handleDecreaseAmount = (key) => {
const database = getDatabase(firebase);
const dbRef = ref(database, `/${key}/amount`);
if (count < 1) {
setCount(0);
} else {
setCount((count -= 1));
set(dbRef, count);
}
};
return (
<div className="App">
<Form
handleSubmit={handleSubmit}
userInput={userInput}
handleUserInput={handleUserInput}
/>
<ul className="listContainer">
{groceryItems.map((item) => {
return (
<GroceryItem
key={item.key}
itemName={item.itemName}
handleDecreaseAmount={() => handleDecreaseAmount(item.key)}
handleIncreaseAmount={() => handleIncreaseAmount(item.key)}
itemAmount={item.amount}
/>
);
})}
</ul>
</div>
);
}
export default App;
firebase.js
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: "AIzaSyBGZuLK5SwXFXRRL4f_IVHeaTfJD8lD5WQ",
authDomain: "grocery-list-app-a7047.firebaseapp.com",
projectId: "grocery-list-app-a7047",
storageBucket: "grocery-list-app-a7047.appspot.com",
messagingSenderId: "282873587634",
appId: "1:282873587634:web:b01a1570bac7ba6b6766ab",
};
const firebase = initializeApp(firebaseConfig);
export default firebase;
Form.js
const Form = ({ handleSubmit, userInput, handleUserInput }) => {
return (
<>
<form action="" onSubmit={handleSubmit}>
<label htmlFor="itemName" className="sr-only">
Add grocery item
</label>
<input
id="itemName"
type="text"
placeholder="Add item (e.g. apples)"
value={userInput}
onChange={handleUserInput}
/>
</form>
</>
);
};
export default Form;
GroceryItem.js
const GroceryItem = ({
itemName,
itemAmount,
handleDecreaseAmount,
handleIncreaseAmount,
}) => {
return (
<li>
<div className="rightItems">
<p className="itemName">{itemName}</p>
</div>
<div className="btnContainer">
<div className="updateBtns">
<p className="itemAmount">{itemAmount}</p>
<button onClick={handleDecreaseAmount}>Decrease amount</button>
<button onClick={handleIncreaseAmount}>Increase amount</button>
</div>
</div>
</li>
);
};
export default GroceryItem;
Solution 1:[1]
Thank you for the insight. I have previously read about the increment operator but will definitely look into this further! I was actually able to find a solution. I do not need to set a state variable as that is the issue that was causing all the values to be overwritten. Instead I came up with this which seems to be working
const handleIncreaseAmount = (key) => {
const database = getDatabase(firebase);
const dbRef = ref(database, `/${key}/amount`);
get(dbRef).then((snapshot) => {
let currentCount = snapshot.val();
currentCount = currentCount + 1;
set(dbRef, currentCount);
});
};
const handleDecreaseAmount = (key) => {
const database = getDatabase(firebase);
const dbRef = ref(database, `/${key}/amount`);
get(dbRef).then((snapshot) => {
let currentCount = snapshot.val();
if (currentCount > 1) {
currentCount = currentCount - 1;
set(dbRef, currentCount);
}
});
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | itsverde |
