0

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
1
  • It's the return router.push('/login') that's causing your issue, get rid of the return statement. Commented May 24, 2020 at 10:49

3 Answers 3

1

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';
}
Sign up to request clarification or add additional context in comments.

Comments

1

In your Component named Index you are checking for error and if it exists you'd want the URL to be changed to "/login" which is correct, but instead of doing this, you are returning router.push() value.

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

Since this is a functional component, as soon as React encounters this return statement in case there is an error, React assumes this return value is what you'd like to render. But since you can not just render objects. React gives you the error about invalid child being present in render.

3 Comments

If I understand I have to remove the return. But if I remove the return, I can change de url but it doesn't redirect to the login component and the app break
That's strange, it shouldn't happen, can you help me with a codesandbox link for the above sample. Omitting that return statement should not break anything. It is very unlikely to cause an error. On a side note, you might try to change the window URL without using the router object. See if that works. Although it would not be the ideal way to handle it.
0

You can just remove the return keyword and it will work without throwing an error:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.