I would like to ask for some help with this, i don't know if its normal or not. Have This components, one is a container that fetch the data and the second one receive the data and display it in a div. Nothing fancy.
const ProjectContainer = () => { // component
const projects = useSelector((state) => state.projectReducer.projects);
const count = useSelector((state) => state.projectReducer.count);
const isDarkMode = useSelector((state) => state.themeReducer.isDarkMode);
const [isLoading, setIsLoading] = useState(false);
const limit = 5;
const dispatch = useDispatch();
useEffect(() => {
console.log("INSIDE USEFFECT");
if (projects.length > 0) return; // avoid fetching data if the state has data already
async function getData() {
setIsLoading(true);
try {
const projectsCollectionRef = db.collection("project-collection");
const projectsCountRef = db
.collection("aggregation")
.doc("project-collection");
console.log("FETCHING DATA");
const responseCount = await projectsCountRef.get();
const count = await responseCount.data().count;
//dispatch
dispatch({ type: "SET_PROJECTS_COUNT", payload: count });
const response = await projectsCollectionRef
.orderBy("createdAt")
.limit(limit)
.get();
let dataSend = [];
response.forEach((document) => {
dataSend.push({ ...document.data(), uid: document.id });
});
//dispatch
dispatch({ type: "SET_PROJECTS", payload: dataSend });
setIsLoading(false);
} catch (error) {
console.error(error);
}
}
getData();
}, [dispatch, projects.length]);
return (
<div className="container mx-auto text-center">
<div>
Proyectos
</div>
{isLoading && projects.length === 0 ? (
<div >
<div id="title">
<p>
Cargando....
</p>
</div>
</div>
) : (
<>
{projects.length === 0 ? (
<div >
<div id="title" >
<p>
No hay proyectos que mostrar....
</p>
</div>
</div>
) : (
<>
<div >
{projects.map((project, index) => {
return (
<Project data={project} index={index} key={project.uid} />
);
})}
</div>
{count !== projects.length && (
<button>
Cargar más
</button>
)}
</>
)}
</>
)}
</div>
);
};
export default ProjectContainer;
The component that shows the data is something like this
import React from "react";
import { useSelector } from "react-redux";
const Project = (props) => {
const { data, index } = props;
console.log({ index });
const isDarkMode = useSelector((state) => state.themeReducer.isDarkMode);
return (
<div>
<div id="image">
<div>
<img
src={data.imageURL}
alt=""
/>
</div>
</div>
<div id="textblock">
<h1 >
{data.name}
</h1>
<div id="description">
<span >{data.description}</span>
<div >
<p>
Tecnologías
</p>
{data.technologies.map((technology) => {
return (
<span key={technology}>
{technology}
</span>
);
})}
</div>
<div >
<div >
<span>
Api Utilizada:
</span>
</div>
<div >
<span>
{data.usedAPI}
</span>
</div>
</div>
</div>
</div>
</div>
);
};
export default Project;
I mean, it works, it does its job, but I don't know if it's correct, in a more realistic company work it should work like this ?
I read that Strict mode can force to do some re renders, but i checked and don't have it.
At the end console looks like this ..
thanks in advance everyone :)
React will re-render once for each dispatch
, even if multiple dispatch
functions are called in the same cycle. This article has some good info on it:
https://medium.com/unsplash/react-redux-performance-considerations-when-dispatching-multiple-actions-5162047bf8a6
Fortunately, there is a solution: the batch
function provided by Redux:
https://react-redux.js.org/api/batch
Just call both of your dispatch
calls from within a batch
, and you should see it only re-render once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With