Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

137
Vistas
no data is passed into state when using useContext/useReducer together with useQuery
export const itemReducer = (state, action) => {
  switch (action.type) {
    default:
      return state
  }
}
import React, { useState, useReducer, createContext, useContext } from 'react'
import { useQuery } from '@apollo/client'
import { CURRENT_MONTH_BY_USER } from '../graphql/queries'
import { itemReducer } from '../reducers/ItemReducer'

const Items = createContext()

export const ItemProvider = ({ children }) => {
  let items = []
  const [state, dispatch] = useReducer(itemReducer, { items: items })

  const result = useQuery(CURRENT_MONTH_BY_USER)
  if (result.data && result.data.getCurrentMonthByUser) {
    items = [...result.data.getCurrentMonthByUser]
  }

  return <Items.Provider value={{ state, dispatch }}>{children}</Items.Provider>
}

export const ItemsState = () => {
  return useContext(Items)
}

export default ItemProvider

let items gets correct data from the useQuery, however nothing is passed into the state, therefore I am unable to transfer data into another components from the context. What am I doing wrong here?

When debugging both items and state they're initially empty because of the loading however then only the items receives correct data and state remains as empty array.

If i put static data into let items it works just fine, so maybe there can be something wrong with my useQuery as well?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

It's easy to see your problem if you look at where items is used. That's only as the initial state to your useReducer call - but items is only set to a non-empty value after this. That has absolutely no effect on the component, because items is not used later in your component function, and the initial state is only ever set once, on the first render.

To solve this you need to embrace your use of a reducer, adding a new action type to set this initial data, and then dispatching that when you have the data. So add something like this to your reducer:

export const itemReducer = (state, action) => {
  switch (action.type) {
    case SET_INITIAL_DATA: // only a suggestion for the name, and obviously you need to define this as a constant
      return { ...state, items: action.items };
    /* other actions here */
    default:
      return state
  }
}

and then rewrite your component like this:

export const ItemProvider = ({ children }) => {
  const [state, dispatch] = useReducer(itemReducer, { items: [] })

  const result = useQuery(CURRENT_MONTH_BY_USER)
  if (result.data && result.data.getCurrentMonthByUser) {
    dispatch({ type: SET_INITIAL_DATA, items: result.data.getCurrentMonthByUser });
  }

  return <Items.Provider value={{ state, dispatch }}>{children}</Items.Provider>
}

Also, while this is unrelated to your question, I will note that your ItemsState export appears to be a custom hook (it can't be anything else since it isn't a component but uses a hook) - that is perfectly fine but there is a very strong convention in React that all custom hooks have names of the form useXXX, which I strongly suggest you should follow. So you could rename this something like useItemsState (I would prefer useItemsContext to make clear it's just a useContext hook specialised to your specific context).

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda