My own realtime chat with react, graphql and postgresql [part 6 - React setup]
Tags: react, graphql, html
Published: 2020-10-28 20:22:52

In the following parts we are going to configure the client, the react app that will consume the api we built [previously](https://dev.to/dalejan/my-own-realtime-chat-with-react-graphql-and-postgresql-part-5-graphql-playground-3p43).

I would recommend to initialize the project with [create-react-app](https://es.reactjs.org/docs/create-a-new-react-app.html), running `npx create-react-app myFrontend` on the console *(npx comes with npm 5.2+)*

We can start with the project structure. I'll use the containers/components pattern, this means centralize the state by a group of 'containers' and print in the dom some fabulous things with the 'components'. 

For this project I built a `Login` and a `Chatroom` containers. We'll be seeing deep down that code in a bit.

Also we'll need a guarded routing system in order to prevent the access of not logged users to the chat. For this I'll use [react-router](https://reactrouter.com/web/guides/quick-start), you can install with `npm install react-router-dom`.

For the styles I'll use sass, you can check out how to implement this [here](https://dev.to/dalejan/how-to-use-sass-in-a-react-project-3i33).

####So let's start coding!

First of all let's build the routing system.

*./routes/app.routes.js*
```javascript
import Login from "../containers/Login/Login";
import Chatroom from "../containers/Chatroom/Chatroom";

const appRoutes = [
  { path: "/login", component: Login },
  {
    path: "/chatroom",
    private: true,
    component: Chatroom,
  },
  { redirect: true, path: "/", to: "/login" },
];

export default appRoutes;

```
The appRoutes array is composed by objects that have path, component, and a private attribute. The redirect flag will allow the react-router to match the root paht `/` to `login` and vice versa.


*./utils/PrivateRoute.jsx*
```javascript
import React from "react";
import { Route, Redirect } from "react-router-dom";

const PrivateRoute = ({ component: Component, to, key }) => {
  const shallPass = false;
  return (
    <Route
      to={to}
      key={key}
      render={(props) =>
        shallPass ? <Component {...props} /> : <Redirect to="/" />
      }
    />
  );
};

export default PrivateRoute;
```

This utility component will use a flag `shallPass` to let a user see the component or redirect to the root. For now, we define the flag as false, but it will be related to the login process.

*./AppRouter.js*

```javascript
import React from "react";
import { Route, Switch, Redirect } from "react-router";
import PrivateRoute from "./utils/PrivateRoute";

const AppRouter = ({ routes }) => {
  return (
    <Switch>
      {routes.map((prop, key) => {
        if (prop.redirect)
          return <Redirect from={prop.path} to={prop.to} key={key} />;
        if (prop.private)
          return (
            <PrivateRoute
              from={prop.path}
              component={prop.component}
              key={key}
            />
          );
        return <Route path={prop.path} component={prop.component} key={key} />;
      })}
    </Switch>
  );
};

export default AppRouter;

```

Lets analize this router:
1. We will use a `routes` array as a prop. This array has the same properties as the `app.routes.js`.
2. Using the `Redirect` component from `react-router` we can show the component depending on the redirect flag.
3. Depending on the private flag we use the `PrivateRoute` guard to secure the navigation.

*./App.jsx*

```javascript
import React from "react";
import { HashRouter } from "react-router-dom";
import AppRouter from "./AppRouter";
import appRoutes from "./routes/app.routes";

const App = () => {
  return <div className="App">
     <HashRouter basename="/">
        <AppRouter routes={appRoutes} />
      </HashRouter>
  </div>;
};

export default App;

```

Let's break this code a little bit:

1. Using [HashRouter](https://reactrouter.com/web/api/HashRouter) we add a base path '#', this is useful if we're going to deploy our frontend in some third party hosting service because of the routing they may have implemented. If you are using your own hosting you could use the [BrowserRouter](https://reactrouter.com/web/api/BrowserRouter).
2. As we saw in the `AppRouter` it recives a routes property, this routes are composed by a pair of path and component so our routing sytem know what to render.

If we run `npm start` you won't be able to see anything, actually you may have some errors, this is because you haven't created the Login and Chatroom containers. In the next part we will start with the `Login` container and the graphql petitions.