Why is this code giving a warning about functions not being valid as a React child?

Viewed 61

The warning is: Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

render() {
    return (
        <div className="App">
            <AppContext.Provider value={this.state}>
                <Navbar> <!-- this is the line React gives warning about -->
                    <Route exact path="/">
                        Welcome to the Library Management System
                    </Route>
                    <Route exact path="/about">
                        The About Page
                    </Route>
                    <Route exact path="/new-books">
                        <NewBooks />
                    </Route>
                    <Route exact path="/my-account">
                        <MyAccount />
                    </Route>
                </Navbar>
            </AppContext.Provider>
        </div>
    );
}

This is what I have in my Navbar.js file:

import React from 'react';
import { BrowserRouter as Router, Switch, Link } from 'react-router-dom';
import './Navbar.css';
import AppContext from "../AppContext";

class UserLoggedInMenu extends React.Component {
    render() {
        return (
            <ul className="navbar-nav ml-auto">
                <li className="nav-item">
                    <Link to="/my-account" className="nav-link">
                        My Account
                    </Link>
                </li>
                <li className="nav-item">
                    <Link to="/logout" className="nav-link">
                        Log Out
                    </Link>
                </li>
            </ul>
        )
    }
};

class UserLoggedOutMenu extends React.Component {
    render() {
        return (
            <ul className="navbar-nav ml-auto">
                <li className="nav-item">
                    <Link to="/my-account" className="nav-link">
                        Log In
                    </Link>
                </li>
            </ul>
        )
    }
};

export default class Navbar extends React.Component {
    render() {
        return (
            <div id="Navbar">
                <AppContext.Provider>
                    {(context) => (
                        <Router>
                            <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
                                <div className="container">
                                    <Link to="/" className="navbar-brand">
                                        Library Management System
                                    </Link>
                                    <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                                        <span className="navbar-toggler-icon"></span>
                                    </button>

                                    <div className="collapse navbar-collapse" id="navbarSupportedContent">
                                        <ul className="navbar-nav mr-auto">
                                            <li className="nav-item">
                                                <Link to="/new-books" className="nav-link">
                                                    New Books
                                                </Link>
                                            </li>
                                        </ul>
                                        {context.userLoggedIn ? <UserLoggedInMenu /> : <UserLoggedOutMenu />}
                                    </div>
                                </div>
                            </nav>

                            <main className="container">
                                <Switch>
                                    {this.props.children}
                                </Switch>
                            </main>
                        </Router>
                    )}
                </AppContext.Provider>
            </div>
        );
    }
}

It seems as though React thinks that <Navbar> was defined as a function, but clearly it isn't.

1 Answers

Providers don't take functions as children:

<AppContext.Provider>
    {(context) => (

You want a consumer:

<AppContext.Consumer>
    {(context) => (

In the future, an easy way to debug this is to start removing components until you find the one causing the error.

Related