Reputation: 882
Hey everyone pretty new to React hooks. I am simply trying to set some reviews that I retrieve from Firebase but cant seem to get it working. I tried a few solutions and I am struggling to get it working any help would be appreciated.
import React, {useContext, useEffect, useState} from 'react';
import firebase from "firebase";
import ReviewsContext from "./review-context";
const Reviews = () => {
const db = firebase.firestore();
let reviews = useContext(ReviewsContext);
let [reviewsLoaded, setReviewsLoaded] = useState(false);
function getReviews(){
db.collection('reviews')
.get()
.then((snapshot) => {
let dataArray = [];
snapshot.docs.forEach(doc => {
dataArray.push(doc.data());
});
reviews = dataArray;
setReviewsLoaded(true);
console.log('reviews', reviews); // logs the correct amount of reviews
})
}
function renderReviews() {
console.log('renderReviews reviewsLoaded', reviewsLoaded); // is true
console.log('renderReviews reviews length', reviews.length); // is 0
if(reviewsLoaded) {
reviews.map((data) => {
return (
<li key={data.name}>
<h3>{data.name}</h3>
<p>{data.position}</p>
</li>
)
});
}
else {
return false
}
}
useEffect(() => {
getReviews(); // this seems to fire before renderReviews
}, []);
return (
<div>
<ul>
{renderReviews()}
</ul>
</div>
)
};
export default Reviews;
Upvotes: 1
Views: 929
Reputation: 667
In this case, the context should be stateful. The way you're doing it currently won't work since context on render will always revert to reviews being empty. Your Provider
component that gives that ReviewContext
should be patterned like below.
import React, { createContext, useState } from "react"
const ReviewContext = createContext()
const ReviewProvider = ({children}) => {
const [reviews, setReviews] = useState([])
return (
<ReviewContext.Provider value={{
reviews: reviews,
setReviews: reviews => setReviews(reviews),
}}>
{children}
</ReviewContext.Provider>
)
}
export default ReviewProvider
export { ReviewContext }
Now, you may do const { reviews, setReviews } = useContext(ReviewContext);
Just call setReviews whenever you want to update reviews in the context.
It's actually stated in the docs as well as I searched it. https://reactjs.org/docs/context.html#dynamic-context
Upvotes: 1