Home > Net >  Functions are not valid as react child Error while using Navigate in react router dom
Functions are not valid as react child Error while using Navigate in react router dom

Time:06-15

I am getting the error ("Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.") when I am trying to use condition which includes Navigate to "/path" (look at the statement in the code).

return (
  <>
    <Router>
      <Navbar bg="dark" variant="dark">
        <Container>
          <Navbar.Brand to="/">MoviesReviews</Navbar.Brand>
          <Nav className="me-auto">
            <Link to="/picks">Picks</Link>
            <Link to="/critics">Critics</Link>
          </Nav>
          <Form className="d-flex">
            <FormControl
              type="search"
              placeholder="Search"
              className="me-2"
              aria-label="Search"
              id = "SearchBox"
            />
            {redirect === true? (() => (<Navigate to = "/search"/>)) : null}
            <Button variant="outline-success" onClick = {() => pressSearch()}>Search</Button>
          </Form>
        </Container>
      </Navbar>
        <Routes>
          <Route path = "/" element = {<Reviews/>}/>
          <Route exact path = "/picks" element = {<Reviews/>}/> 
          <Route exact path = "/critics" element = {<Critics/>}/>
          <Route exact path = "/search" element = {<SearchReviews search = {searchString}/>}/>
        </Routes>
    </Router>
  </>
);

If you look at the Route exact path for "/search", you see that I am actually returning a <Component/>. I am pretty sure the problem is in the line which contains the condition ({redirect === true? (() => (<Navigate to = "/search"/>)) : null}).

CodePudding user response:

{redirect === true? (() => (<Navigate to = "/search"/>)) : null} with the above statement you :

  1. in false case you are returning null.
  2. in true case you are trying to render a function.
() => (<Navigate to = "/search"/>)

Hence it is not valid as a react child.

You have to do : {redirect === true ? <Navigate to="/search"/> : null} as mentioned in comments.

CodePudding user response:

Functions are not valid JSX, they can't be rendered.

If you are conditionally rendering React components there are a couple syntaxes you can use, neither involves using a function.

  • Using a ternary: condition ? <Component1 /> : null

    {redirect ? <Navigate to="/search" replace /> : null}
    

    This is useful if you need to conditionally render one of two different components, or to return null as a component result.

  • Using logical AND (&&): condition && <Component1 />

    {redirect && <Navigate to="/search" replace />}
    

    This is useful if you only need to conditionally render a single component.

If you are conditionally rendering the entire component render result then you should use the first in order to return null as valid JSX.

Suggestion

It would be better to issue an imperative redirect instead of setting any redirect state. This has the benefit of not requiring an additional React render cycle to effect the change.

Example:

import { useNavigate } from 'react-router-dom';

...

const Component = () => {
  const navigate = useNavigate();

  ...

  // logic to replace setting any `redirect` state
  if (<condition to redirect>) {
    navigate("/search", { replace: true });
  }

  ...

  return (
    <>
      <Router>
        <Navbar bg="dark" variant="dark">
          <Container>
            <Navbar.Brand to="/">MoviesReviews</Navbar.Brand>
            <Nav className="me-auto">
              <Link to="/picks">Picks</Link>
              <Link to="/critics">Critics</Link>
            </Nav>
            <Form className="d-flex">
              <FormControl
                type="search"
                placeholder="Search"
                className="me-2"
                aria-label="Search"
                id = "SearchBox"
              />
              <Button
                variant="outline-success"
                onClick={pressSearch}
              >
                Search
              </Button>
            </Form>
          </Container>
        </Navbar>
          <Routes>
            <Route path="/" element={<Reviews />} />
            <Route path="/picks" element={<Reviews />} /> 
            <Route path="/critics" element={<Critics />} />
            <Route path="/search" element={<SearchReviews search={searchString} />} />
          </Routes>
      </Router>
    </>
  );
};
  • Related