Search code examples
reactjsgraphqlapollo

REact error Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead


I am trying to login into my app. But I get an error saying: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead. I can login but i don't want to clean this error. Thanks for you help enter image description here

Component Myapp

import { ApolloProvider } from '@apollo/client'
import client from '../config/apollo'
import StateOrder from '../Context/Orders/StateOrder'
import '../styles.css'
const MyApp = ({ Component, pageProps }) => {
  return (
    <ApolloProvider client={client}>
      <StateOrder>
        <Component {...pageProps} />
      </StateOrder>
    </ApolloProvider>
  )
}
export default MyApp

Component index

import Layout from '../Components/Layout'
import Client from '../Components/Client'
import { gql, useQuery } from '@apollo/client'
import { useRouter } from 'next/router'
import Link from 'next/link'

const GET_CLIENTS_BY_USER = gql`
query getClientsBySalesman{
  getClientsBySalesman{
    id
    name
    surname
    company
    email
  }
}`

const Index = () => {
  const router = useRouter()
  const { data, loading, error } = useQuery(GET_CLIENTS_BY_USER)

  if (loading) return <p className="my-2 bg-blue-100 border-l-4 border-blue-700 p-4 text-center">Carregant...</p>

  if (error || !data.getClientsBySalesman) {
    localStorage.removeItem('token');
    return router.push('/login')
  }

  return (
    <div>
      <Layout>
        <h1 className="text-2xl text-gray-800">Clients</h1>
        <Link href="/nouclient">
          <a className="bg-blue-800 py-2 px-5 mt-3 inline-block text-white rounded text-sm hover:bg-gray-800 uppercase w-full lg:w-auto text-center">Nou Client</a>
        </Link>
        <div className="sm:overflow-x-scroll">
          <table className="table-auto shadow-md mt-10 w-full w-lg">
            <thead className="bg-gray-800">
              <tr className="text-white">
                <th className="w-1/5 py-2">Nom</th>
                <th className="w-1/5 py-2">Empresa</th>
                <th className="w-1/5 py-2">Email</th>
                <th className="w-1/5 py-2">Eliminar</th>
                <th className="w-1/5 py-2">Editar</th>
              </tr>
            </thead>
            <tbody className="bg-white">
              {data.getClientsBySalesman.map(client => (
                <Client
                  key={client.id}
                  client={client} />
              ))}
            </tbody>
          </table>
        </div>
      </Layout>
    </div >
  )
}
export default Index

Component StateOrder

import React, { useReducer } from 'react'
import ContextOrder from './ContextOrder'
import ReducerOrder from './ReducerOrder'

import {
  SELECT_CLIENT,
  SELECT_PRODUCT,
  PRODUCT_QUANTITY,
  UPDATE_TOTAL
} from '../../types'

const StateOrder = ({ children }) => {
  const initialState = {
    client: {},
    products: [],
    total: 0
  }
  const [state, dispatch] = useReducer(ReducerOrder, initialState)
  const addClient = client => {
    dispatch({
      type: SELECT_CLIENT,
      payload: client
    })
  }

  const addProduct = selectProducts => {
    let newState
    if (state.products.length > 0) {
      newState = selectProducts.map(product => {

        const newObject = state.products.find(productState => productState.id === product.id);
        return { ...product, ...newObject }
      })
    } else {
      newState = selectProducts;
    }
    dispatch({
      type: SELECT_PRODUCT,
      payload: newState
    })
  }

  const productQuantity = newProduct => {
    dispatch({
      type: PRODUCT_QUANTITY,
      payload: newProduct
    })
  }

  const updateTotalOrder = () => {
    dispatch({
      type: UPDATE_TOTAL
    })

  }
  return (
    <ContextOrder.Provider
      value={{
        client: state.client,
        products: state.products,
        total: state.total,
        addClient,
        addProduct,
        productQuantity,
        updateTotalOrder
      }}
    >
      {children}
    </ContextOrder.Provider>
  )
}
export default StateOrder

Solution

  • You can try something like this, I had the same mistake and it worked for me. What I understand is that when you return the router.push('/login') the default router of next.js calls a promise and so the exception is generated.

    if (!data.getClientsBySalesman) {
        window.location.href = 'login';
    }