React Router
React router is used for declarative routing in React. React Router uses a model
called "dynamic routing". It means that routing takes place as your app is
rendering, and not via a configuration or convention outside of the running app.
To install React Router, run the following command:
Then, run the following command:
This creates App.jsx
file.
The App.jsx
component will act as the entry point for all our rendering.
Let's also add loading state into this component so that in upcoming sections we
can set the axios headers synchronously.
Paste the following contents into App.jsx
:
Once the components are created and routing is implemented in the following
chapters, we should be able to see the Home
and About
components being
rendered. This forms the basis for react-router
.
Axios
Axios is a promise based HTTP client for the browser and Node.js. To install
axios
, run the following command:
HTTP requests can be sent easily by using different methods in axios
.
For example axios.get('https://httpbin.org/get')
will send a GET
request to the
specified URL.
The axios
requests are mostly async
in nature. Thus at BigBinary we always
embed all async
blocks within the try-catch
blocks to ensure that the code
catches any exceptions that might occur as part of the call.
Adding async
calls within try-catch
block also helps in debugging.
Axios headers and defaults
Interceptors are methods which are triggered before the main method. A
request interceptor
is called before the actual call to the endpoint is made
and a response interceptor
is called before the promise is completed and the
data is received from the callback:
This creates a file axios.js
inside apis
directory.
As starters, we will use this file to set out Axios headers.
Rails by default adds CSRF counter measures for all requests.
Thus even for AJAX calls, we will have to provide a CSRF token, so that Rails
will understand that the request is trust worthy.
In the upcoming chapters, when we reach authentication part, we need a scalable
mechanism by which we can send the authentication token to our backend server
with each request.
For all these cases, setting the Axios headers is the solution.
Paste the following to axios.js
:
setAuthHeaders
is a function invoked from application.js
.
The CSRF token will be set in the X-CSRF-TOKEN
header.
It then sets the page to loading and the function sets default headers from
X-Auth-Email
and X-Auth-Token
.
The email
and token
will come into action once we reach the chapter dealing
with authentication.
These tokens will then be sent with every request to the backend server.
Now we need to invoke the setAuthHeaders
method in application.js
, as its code executes prior to the initial rendering of the React component, making it the ideal location to handle initializations.
Fully replace app/javascript/packs/application.js
with the following code:
JavScript Logger
Our ESlint
config does not allow us to use console.log
inside of our app.
You can read more about why we should avoid console.log
in general over
here.
The following line is how we have added a rule inside of our ESlint
config
that marks all console
statements as errors:
However, during API calls to server or while communicating with another external
service, errors are bound to occur. In such cases, we might want to log the
errors that are caught from our try-catch
block.
We can use js-logger
in such cases. js-logger
is a lightweight JavaScript
Logger that has zero dependencies.
During the setup of Shakapacker, we had already installed the necessary packages, specifically js-logger
and babel-plugin-js-logger
.
To initialize js-logger
, run the following command from the root of project:
Inside logger.js
, paste the following:
If you wish to use the logger.js
file from the
Wheel repository,
then you can do so using the following command:
Typically, you would need to manually add the js-logger
plugin to your babel.config.js
file. However, our provided babel.config.js
file from wheel
already includes the js-logger
plugin, as shown below. Therefore, there is no need for you to modify the babel.config.js
file.
Then, invoke initializeLogger()
from application.js
as follows:
On running your server, you would see that js-logger
won't log any of the
messages in the browser console even if you add logger statements like logger.info("Never use console.log");
in the App.jsx
component.
The reason is that we haven't mounted the App.jsx
component into our Rails
view pipeline yet.
We will talk more the mounting and how to do that in the
chapter for API based architecture.
Since no routes or components have been set in the Rails pipeline, it will by
default show a welcome page that it comes shipped with.
Currently there is no use case of logging from App.jsx
.
CSRF token authenticity verification error
If you ever encounter the ActionController::InvalidAuthenticityToken
error,
then it means that your Axios requests are not sending the CSRF token while
making requests to Rails server.
Thus the first point to check would be axios.js
file and check whether code to
set default headers have been added or not. Compare your axios.js
file with
the code given in the previous section.
Aliases
Aliases allows us to create aliases to import or require certain modules more
easily. Instead of doing:
We can define an alias for the apis
folder so that it can be accessed from any
component without having to do relative import.
To do so, edit resolve.js
as follows:
Now, you can import
from apis
folder without having to resolve the entire
path each time.
Example:
Now let's commit these changes: