Eu fiz o curso e apliquei também em outras situações. Mas tive um problema: múltiplas renderizações. No aplicativo (um blog simples) que estou desenvolvendo aplicando o que foi ensinado no curso eu criei um AppContext para guardar contextos da aplicação, como postagens em destaques, categorias, etc.
Esse é o código do AppContext
import React, { createContext, useReducer } from 'react';
import { reducer } from './../reducers/appDataReducer';
export const AppContext = createContext();
const initialState = {
categorias: [],
destaques: [],
videosEmDestaque: []
}
export const AppProvider = ({children}) => {
const [appData, dispatch] = useReducer(reducer, initialState);
return (
<AppContext.Provider value={{appData, dispatch}}>
{children}
</AppContext.Provider>
);
}
Fiz um reducer, para lidar com os estados
export const FETCH_CATEGORIAS = 'FETCH_CATEGORIAS';
export const FETCH_DESTAQUES = 'FETCH_DESTAQUES';
export const FETCH_VIDEOS_DEVOCIONAIS_EM_DESTAQUE = 'FETCH_VIDEOS_EM_DESTAQUE';
export const reducer = (state, action) => {
console.log('action', action)
switch(action.type) {
case FETCH_CATEGORIAS:
return {...state, categorias: action.payload}
case FETCH_DESTAQUES:
return {...state, destaques: action.payload}
case FETCH_VIDEOS_EM_DESTAQUE:
return {...state, videosEmDestaque: action.payload}
default:
return state;
}
}
Aí eu fiz um hook para lidar com os fetchs e dispatches
import { useContext } from "react";
import { AppContext } from "../context/AppContext";
import { FETCH_CATEGORIAS, FETCH_DESTAQUES, FETCH_VIDEOS_EM_DESTAQUE } from './../reducers/appDataReducer';
import axios from './../plugins/axios/axios';
const fetchCategoriasAction = (payload) => ({
type: FETCH_CATEGORIAS,
payload: payload
});
const fetchDestaquesAction = (payload) => ({
type: FETCH_DESTAQUES,
payload: payload
});
const fetchVideosEmDestaqueAction = (payload) => ({
type: FETCH_VIDEOS_EM_DESTAQUE,
payload: payload
});
export const useAppContext = () => {
const { appData, dispatch } = useContext(AppContext);
const { categorias, destaques, videosEmDestaque } = appData;
const fetchCategorias = () => {
if (!categorias.length) {
axios.get('/categorias')
.then(response => dispatch(fetchCategoriasAction(response.data)))
.catch(error => console.log(error));
}
};
const fetchDestaques = () => {
if(!destaques.length){
axios.get('/postagens/destaques')
.then(response => dispatch(fetchDestaquesAction(response.data)))
.catch(error => console.log(error));
}
};
const fetchVideosEmDestaque = () => {
if(!videosEmDestaque.length){
axios.get('/videos/destaques?categoriaId=1')
.then(response => dispatch(fetchVideosEmDestaqueAction(response.data)))
.catch(error => console.log(error));
}
}
return {
destaques,
categorias,
videosEmDestaque,
fetchCategorias,
fetchDestaques,
fetchVideosEmDestaque,
}
}
Com isso pronto, pensei poder usar o Hook para lidar com os estados da aplicação, algo similar ao Redux. Mas é aqui que estou enfrentando dificuldade. Sempre que o chamo em algum componente da aplicação, ele faz múltiplas renderizações. Por exemplo: em Layout.jsx eu faço essa chamada:
///...
const Layout = ({children, hasSidebar = true}) => {
const { destaques, categorias, fetchCategorias } = useAppContext();
useEffect(() => {
fetchCategorias();
}, []);
//...
Ela gera 4 chamadas do request para o back-end. Não estou sabendo como resolver, já que não é um dado computado.