Basic Routing ============= The first step is to implement some basic routing functionality. Unlike Ember, React does not come with routing functionality built in. We thus need to install some additional packages to implement routing: .. code-block:: console $ yarn add react-router-dom The first route we will implement is the login page. Create a new file ``src/js/routes/login.jsx`` and then add the following content: .. code-block:: jsx import React, { useState } from "react"; function Login() { const [email, setMail] = useState(""); const [password, setPassword] = useState(""); const [loginValid, setLoginValid] = useState(true); const updateEmail = (ev) => { setMail(ev.target.value); }; const updatePassword = (ev) => { setPassword(ev.target.value); }; const handleLogin = (ev) => { ev.preventDefault(); if (email === "test@example.com" && password === "password") { setLoginValid(true); } else { setLoginValid(false); } }; let errorTag = null; let errorLabel = null; let errorInput = null; if (!loginValid) { errorTag = ( No user exists with the e-mail address {email} or the password is incorrect. ); errorLabel = "text-danger"; errorInput = "form-control is-invalid"; } else { errorLabel = null; errorTag = null; errorInput = "form-control" } return (

Login

) } export default Login; This is the same code that in the first tutorial we had in the ``athena.jsx`` file. Update the ``athena.jsx`` to remove the code we just copied, so that the file looks like this: .. code-block:: jsx import React from 'react'; import ReactDOM from 'react-dom'; import AriaMenu from './components/aria-menu.jsx'; import Login from './routes/login.jsx'; import '../styles/app.scss'; function Athena { return (
) } ReactDOM.render(, document.getElementById("app-entry-point")); } The main changes are that we import the ``Login`` component and that we then output that component to generate the application. At this point we do not have any routing functionality and in order to implement that, we included an option to our ``devServer`` section of``webpack.conf.js`` last week. The option was ``historyApiFallback`` and as a reminder, it should look like that: .. code-block:: js ... devServer: { static: { directory: path.resolve(__dirname, "dist"), }, open: false, historyApiFallback: true, }, ... The reason we needed to include this, is that when we implement the routing functionality, this will update the URL that is shown in the browser. When we then update the code and re-load the page, the browser will try and re-load the updated URL, but this URL does not actually exist for the web-server, it only exists within the React application itself. By setting the ``historyApiFallback`` option, we are basically telling the web-server that all requests should always be mapped to the ``index.html`` file and that the JavaScript code will take care of distinguishing the different routes of the application. The second change we need to make is to the ``index.html`` template, adding the ```` tag: .. code-block:: html <%= htmlWebpackPlugin.options.title %> <% for (var css in htmlWebpackPlugin.files.css) { %> <% } %> The ```` tag defines the base URL, from which all relative URLs, such as the ones in the ```` or ``