My code throwing "Rendering<Context>directly is not supported" and "A context consumer was rendered with multiple children" errors

Viewed 35

I am trying to make a chat website, and i was following along to this YouTube tutoriel and I came across these two errors:

"Renderingdirectly" is not supported and "A context consumer was rendered with multiple children"

Here is my App code:

import React from 'react';
import ApolloProvider from './ApolloProvider';
import {Container} from 'react-bootstrap'
import Register from './pages/register'
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'
import './App.scss';
import Login from './pages/Login';
import Home from './pages/Home'
import {AuthProvider} from './context/auth';

function App() {

  return (
    <ApolloProvider >
      <AuthProvider>
        <Router>
          <Container className='pt-5'>
            <Routes>
            <Route exact path='/' element={<Home />}/>
              <Route  path='/register' element={<Register />}/>
              <Route  path='/login' element={<Login />}/>
            </Routes>
          </Container>
        </Router>
      </AuthProvider>
   </ApolloProvider>
  );
}

export default App;

And here is my context code ( I am setting the token in my LOGIN case, which is being accessed from my login.js):

import React, {createContext, useReducer, useContext} from 'react'

const AuthStateContext = createContext()
const AuthDispatchContext = createContext()
const authReducer = (state, action) =>{
    switch(action.type){
        case 'LOGIN':
            localStorage.setItem("token", action.payload.token)
            return {
                ...state,
                user: action.payload,
            }
            case 'LOGOUT':
                return {
                    ...state,
                    user: null
                }
            default:
                throw new Error(`Unknown action type: ${action.type}`)
    }
}

export const AuthProvider = (props) => {
    const [state, dispatch] = useReducer(authReducer, {user: null})
    return (
       <AuthDispatchContext.Provider value={dispatch}>
            <AuthStateContext value={state}>
                {props.children}
            </AuthStateContext>
       </AuthDispatchContext.Provider>
    )
}

export const useAuthState = () => useContext(AuthStateContext)
export const useAuthDispatch = () => useContext(AuthDispatchContext)

Here is a snippet of my login code where we pass the token to the context file:

import { useAuthDispatch } from '../context/auth';

const LOGIN_USER = gql`
  query login(
    $username: String! 
    $password: String! 
  
    ) {
    login(
        username: $username 
        password: $password 
    
        ) {
      username email createdAt token
    }
  }
`;


export default function Login() {
    const [variables, setVariables]= useState({
        username: '',
        password: ''
    })
    const Navigate = useNavigate()
    const [errors,setErrors] = useState({})

    const dispatch = useAuthDispatch()

    const [loginUser, {loading}] = useLazyQuery(LOGIN_USER,{
        onError: (err)=>{
            setErrors(err.graphQLErrors[0].extensions.errors)
        },
        onCompleted: (data)=>{
                dispatch({type:'LOGIN', payload: data.login})
                Navigate('/')
        }

      })
   const submitLogin = (e) =>{
    e.preventDefault()
    loginUser({variables})
   }
1 Answers

You are rendering AuthStateContext while it should be AuthStateContext.Provider, like so:

export const AuthProvider = (props) => {
    const [state, dispatch] = useReducer(authReducer, {user: null})
    return (
       <AuthDispatchContext.Provider value={dispatch}>
            <AuthStateContext.Provider value={state}>
                {props.children}
            </AuthStateContext.Provider>
       </AuthDispatchContext.Provider>
    )

Related