Ibrahim Noor
Ibrahim Noor

Reputation: 259

Why is my useHistory undefined even when it is within the Router?

I am trying to use history.push from a react component but it is throwing an error that history is undefined.

This index.js file:

ReactDOM.render(
  <React.Fragment>
    <Provider store={store}>
      <Router>
        <App />
      </Router>
    </Provider>
  </React.Fragment>,
  document.getElementById("root")
);

This is App.js:

function App() {
  return (
        <AuthenticatedUser>
          <Routers></Routers>
        </AuthenticatedUser>
  );
}

The Routers.js file contains all the routes within switch:

export default function Routers() {
  return (
    <Switch>
      <Route exact path="/" component={Books}></Route>
      <Route exact path="/login" component={LoginForm}></Route>
      <Route exact path="/librarians" component={Librarians}></Route>
      <Route exact path="/customers" component={Customers}></Route>
      <Route
        exact
        path="/all-borrowed-books"
        render={(props) => <BorrowedBooks {...props} all={true} />}
      ></Route>
      <Route exact path="/my-borrowed-books" component={BorrowedBooks}></Route>
      <Route
        exact
        path="/all-returned-books"
        render={(props) => <ReturnedBooks {...props} all={true} />}
      ></Route>
      <Route exact path="/my-returned-books" component={ReturnedBooks}></Route>
      <Route exact path="/register" component={SignUpForm}></Route>
    </Switch>
  );
}

And my AuthenticatedUser.js file:

function AuthenticatedUser(props) {
  return (
    <>
      <SideMenu />
      <Header />  
      <div>{props.children}</div>
    </>
  );
}

export default AuthenticatedUser;

Now in my Header.js file where I am getting the error, I am trying to use useHistory hook for history.push in the logout function. This is the code:

const Header = (props) => {
  const classes = useStyles();
  const { history } = useHistory();
  const logOut = () => {
    history.push('/login')
    // clearLocalStorage();
  };

  return (
    <AppBar position="static" className={classes.root}>
      <Toolbar>
        <Grid container alignItems="center">
          <Grid item>
            <InputBase
              placeholder="Seach topic"
              className={classes.searchInput}
              startAdornment={<SearchIcon fontSize="small" />}
            />
          </Grid>
          <Grid item sm></Grid>
          <Grid item>
            <ActionButton onClick={logOut}>
              <ExitToAppIcon></ExitToAppIcon>
            </ActionButton>
          </Grid>
        </Grid>
      </Toolbar>
    </AppBar>
  );
};

export default Header;

From my own knowledge, since my App component is within BrowserRouter, All the component within app should have access to brower history. but clearly I am wrong. Can someone please clearify.

Upvotes: 0

Views: 633

Answers (1)

Carl Pryke
Carl Pryke

Reputation: 349

As per the docs:

https://reactrouter.com/web/api/Hooks/usehistory

useHistory returns a single History instance, not an object with a history instance member


  const history = useHistory()

by using destructuring, you are effectively referencing history.history, which does not exist.

Upvotes: 3

Related Questions