Por favor, ayúdame a entender por qué no recibo artículos en la primera solicitud. Tengo este componente ExportData que llama a Context solo cuando se le solicita, dialogConfirmation está vinculado a un botón, fragmento:
Exportar datos:
import useItem from '../../context/ItemsContext' const ExportData = () => { const { items, getAll } = useItem() const dialogConfirmation = confirm => { if (confirm) { getAll() } } }ElementosContexto:
import React, { useState, useReducer, createContext, useContext, useEffect, } from 'react' import { useQuery } from '@apollo/client' import { CURRENT_MONTH, ALL_ITEMS } from '../graphql/queries' import itemReducer from '../reducers/itemReducer' export const ItemProvider = ({ children }) => { let items = [] const [all, setAll] = useState(false) const selectedMonth = dayjs(new Date()).format('YYYY-MM') const [state, dispatch] = useReducer(itemReducer, []) const result = useQuery(all ? ALL_ITEMS : CURRENT_MONTH, { variables: all ? null : { selectedMonth }, }) if (result.data && result.data.getCurrentMonth) { items = [...result.data.getCurrentMonth] } if (result.data && result.data.getItems) { items = [...result.data.getItems] } useEffect(() => { if (result.data && result.data.getCurrentMonth) { dispatch({ type: 'ALL', items: result.data.getCurrentMonth, }) } if (result.data && result.data.getItems) { dispatch({ type: 'ALL', items: result.data.getItems, }) } }, [result.data]) const getAll = () => { setAll(true) } const value = { items: state.items, getAll, } return <ItemContext.Provider value={value}>{children}</ItemContext.Provider> }Reductor:
const itemReducer = (state, action) => { switch (action.type) { case 'ALL': return { ...state, items: action.items, } default: return state } }La consulta CURRENT_MONTH devuelve solo elementos del mes actual; ese debería ser el predeterminado.
La consulta ALL_ITEMS devuelve todos los elementos de la base de datos.
Lo que sucede actualmente, cuando uso la función getAll en ExportData , en el primer intento, devuelve solo los elementos del mes actual; sin embargo, en el segundo intento, devuelve la salida correcta (todos los datos).
Al depurar itemReducer, todos los elementos están en action.items sin embargo, la salida dentro del componente solo obtiene los datos antiguos... Sin embargo, en el segundo intento, funciona bien.
¿Qué estoy haciendo mal aquí?
Que está sucediendo aquí:
useEffect s son disparados: (dentro del componente) no hace nada, (dentro useQuery ) dispara la solicitud a gql apiuseQuery se establece con datosstate.items porque el envío aún no se activó)useEffect s se disparan y esta vez se llama a dispatch. En este proceso reaccionan los renders 3 veces. Si coloca console.log(state.items) dentro del componente, se verá así:
[] // no data yet [] // data is present but not yet used by `state` [<your data>] // data is present and used by statePuede resolver eso eliminando useEffect y useReducer:
useEffect s son disparados: (dentro del componente) no hace nada, (dentro useQuery ) dispara la solicitud a gql apiuseQuery se establece con datos En este proceso reaccionan los renders 2 veces. Si coloca console.log(items) dentro del componente, se verá así:
[] // no data yet [<your data>] // data is present and used import React, { useState, createContext, useContext, } from 'react' import { useQuery } from '@apollo/client' import { CURRENT_MONTH, ALL_ITEMS } from '../graphql/queries' export const ItemProvider = ({ children }) => { const [all, setAll] = useState(false) const selectedMonth = dayjs(new Date()).format('YYYY-MM') const result = useQuery(all ? ALL_ITEMS : CURRENT_MONTH, { variables: all ? null : { selectedMonth }, }) const getAll = () => { setAll(true) } const items = result?.data.getCurrentMonth || result?.data.getItems || [] const value = { items, getAll, } return <ItemContext.Provider value={value}>{children}</ItemContext.Provider> }