i am trying to make a visitor counter using React and Firebase but i am stuck at a point where i am unable to save the data in the state.
const [visitor, setVisitor] = useState([]);
const [visitorCount, setVisitorCount] = useState(0);
// const [id, setId] = useState(null);
const visitorCollectionRef = collection(db, "visitor_counter");
const addVisitor = async () => {
console.log("here");
await addDoc(visitorCollectionRef, {
visitorCount,
id: "",
created: serverTimestamp(),
});
};
const updateVisitor = async (id) => {
console.log("here");
// // await updateDoc();
};
useEffect(() => {
const getVisitor = async () => {
const data = await getDocs(visitorCollectionRef);
setVisitor(data.docs.map((doc) => ({ ...doc.data(), id: doc.id }))); // problem shows here
console.log(visitor);
if (data.docs.length === 1) {
updateVisitor(visitorCount);
} else {
addVisitor();
}
};
getVisitor();
}, []);
The error i am gettin is
Uncaught Error: Objects are not valid as a React child (found: object with keys {visitorCount, created, id}). If you meant to render a collection of children, use an array instead.
at throwOnInvalidObjectType (react-dom.development.js:14887:1)
at createChild (react-dom.development.js:15139:1)
at reconcileChildrenArray (react-dom.development.js:15404:1)
at reconcileChildFibers (react-dom.development.js:15821:1)
at reconcileChildren (react-dom.development.js:19174:1)
at updateFragment (react-dom.development.js:19514:1)
at beginWork (react-dom.development.js:21640:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
I have debugged my code in every possible way, and problem shows only when calling
setVisitor
function to set data.
Please ignore if any mistake, i am a beginner.
CodePudding user response:
It looks like the issue is caused by the fact that you are trying to render an object as a child in your React component. In React, you can only render a string, a number, a boolean, null, or an array of elements as children. You cannot render an object directly.
In your code, you are trying to set the visitor state to an array of objects using the setVisitor function:
setVisitor(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
This will cause the error you are seeing because you are trying to render an array of objects as children in your component.
To fix this issue, you will need to render the data contained in the objects in the visitor array as individual elements or components. For example, you could use the .map() function to create an array of elements from the visitor array and render them in your component:
{visitor.map(item => (
<div>
<p>Visitor Count: {item.visitorCount}</p>
<p>ID: {item.id}</p>
<p>Created: {item.created}</p>
</div>
))}
Alternatively, you could create a separate component to render each item in the visitor array and pass the item data to the component as props:
{visitor.map(item => (
<VisitorItem
visitorCount={item.visitorCount}
id={item.id}
created={item.created}
/>
))}
I hope this helps! Let me know if you have any questions.