1

I am using Router and customHistory to help me redirect the pages, but the pages not render correctly.

The code works like this: if the user is authorized or log in, then the user should be redirected to "localhost:8080/dashboard" and see the dashboard(with data fetching from firebase) & header; if the use is log out, then the user should be redirect to "locahost:8080/" and see the log in button with the header.

However, after I successfully log in, the url is "localhost:8080/dashboard" without any data fetched from firebase, only things I can see are the header and login button. But if I hit "RETURN" with the current url which is "localhost:8080/dashboard", it will redirect to correct page with all data fetching from firebase, and no login button.

This is the github_link to the code. I have spent times searching online, but do not find any positive result except this one. After reading the stackoverflow I feel my code has some problems with asynchronization. Any thoughts?

I really appreciate for your help! Thanks!

This is my AppRouter.js:

export const customHistory = createBrowserHistory();
const AppRouter = () => (
  <Router history={customHistory}>
    <div>
      <Header />
      <Switch>
        <Route path="/" exact component={LoginPage} />
        <Route path="/dashboard" component={ExpenseDashboardPage} />
        <Route path="/create" component={AddExpensePage} />
        <Route path="/edit/:id" component={EditExpensePage} />
        <Route path="/help" component={HelpPage} />
        <Route component={LoginPage} />
      </Switch>
    </div>
  </Router>
);

This is my app.js

import React, { Children } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";

import "normalize.css/normalize.css"; //Normalize.css makes browsers render all elements more consistently and in line with modern standards.
import "./styles/styles.scss";
import AppRouter, { customHistory } from "./routers/AppRouter";
import configureStore from "./redux/store/configStore";
import { startSetExpenses } from "./redux/actions/expenses";
import { login, logout } from "./redux/actions/auth";

import "react-dates/lib/css/_datepicker.css";
import { firebase } from "./firebase/firebase";
//for testing: npm test -- --watch

const store = configureStore();
const jsx = (
  <Provider store={store}>
    <AppRouter />
  </Provider>
);

ReactDOM.render(<p>Loading...</p>, document.getElementById("app"));

let hasRendered = false;
const renderApp = () => {
  if (!hasRendered) {
    ReactDOM.render(jsx, document.getElementById("app"));
    hasRendered = true;
  }
};

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    console.log("log in");
    store.dispatch(login(user.uid));
    store.dispatch(startSetExpenses()).then(() => {
      renderApp();
      if (customHistory.location.pathname === "/") {
        customHistory.push("/dashboard");
      }
    });
  } else {
    console.log("log out");
    store.dispatch(logout());
    renderApp();
    customHistory.push("/");
  }
});

This is the header.js

import React from "react";
import { BrowserRouter, Route, Switch, Link, NavLink } from "react-router-dom";
import { connect } from "react-redux";
import { startLogout } from "../redux/actions/auth";

export const Header = ({ startLogout }) => (
  <header>
    <h1>Expensify</h1>
    <NavLink to="/" activeClassName="is-active">
      Dashboard
    </NavLink>
    <NavLink to="/create" activeClassName="is-active">
      CreateExpense
    </NavLink>
    <button onClick={startLogout}>Logout</button>
  </header>
);

const mapDispatchToProps = (dispatch) => ({
  startLogout: () => dispatch(startLogout()),
});

export default connect(undefined, mapDispatchToProps)(Header);

0 Answers0