The Lockdown Coder: Components and classes and hooks, oh my!

Photo by Mstudio from Pexels

My React apps were taking shape and I was ticking off more and more UI challenges I had set myself and was experimenting with different APIs, in particular having fun with Google Maps.

In my freeCodeCamp course I had learned how to create React components as class components and functional components. There were distinctions in stateless and stateful components and an overview on lifecycle methods (e.g. componentDidMount ). All of this was super helpful and it works. However, when I got stuck and needed guidance from the internet I got confused because other developers were using React Hooks in their code and it wasn’t something I was familiar with. Sigh. Here we go again with the deep dive.

What are React hooks?

When we create class components in React we can use this.state to manage and access data in that component. We can also lean on lifecycle methods like componentDidMount to ensure certain functions run at defined moments.

With React Hooks we can do the same things but in a more streamlined manner. To manage local state there is useState and lifecycle methods are now managed as ‘side effects’ handled in useEffect . It’s worth noting that hooks cannot be used inside class components and you need to use function components instead. React says, ‘in the longer term, we expect Hooks to be the primary way people write React components’.

Mine is a simplistic explanation and hooks are more powerful than I currently understand but this is how I appreciate it.

Given how it seems hooks are here to stay, I set about learning how they work and how to convert my existing project to use them instead. There was definitely a learning curve but now I am comfortable using hooks I can’t imagine going back.

Photo by David Music from Pexels

All aboard the Express train

I got to the point where I wanted to create a contact form to collect a name, email and message and have those details sent to a specific email address. These contact forms are so commonplace I thought they couldn’t be difficult to make, surely? I was able to create my HTML form easily enough and had set the data to useState hooks so I could retrieve it when I needed it.

Next up, I needed to find out how to send emails. I found several articles and tutorials that referenced either Nodemailer or EmailJS. I didn’t know much more at this stage to be honest so I went with Nodemailer.

Nodemailer describes itself as “a module for Node.js applications to allow easy as cake email sending”. My take away from that was “easy as cake email sending”. Sounded good! I remembered I had Node.js installed already so I figured I was set. At the time I had no appreciation for how Node.js differed from my React app. I simply followed a tutorial and didn’t question anything as it worked and that’s all I cared about at that moment.

What I effectively did was create a custom server (and called it server.js ) using the Express framework. I imported Nodemailer into my server.js file and followed instructions to configure the Nodemailer settings to send from my Gmail account. I then added a POST route set to /email . Now, from my React app I could make a POST request to this URL endpoint /email and send data with the request. In this example, the data I was sending was the name, email and message. When the custom Express server received a request at the /email endpoint it would take the request data and use it in Nodemailer to send the email.

I had created my own API endpoint and didn’t even realise it. Whilst my server.js file sat innocuously like any other file in my app’s directory it was actually much more than that. Harnessing the power of Node.js, Express made it super easy to create a custom server. You still use Javascript in the Node environment and can bring in packages from the npm repository (like Nodemailer and Express). When you create POST routes you are creating opportunities for your React app to make contact with your server and pass data which can be used on the server-side.

As the name suggests, Nodemailer requires the Node.js environment to run so that’s what we used. However, when else might you want to run code on the server side? Why not do everything client side if you can? This topic runs deep and the way I understand it best is through security and performance.

Client-side vs server-side

Photo by Badhan Ganesh on Unsplash

My React app allows me to run Javascript code on the client-side, the front-end, in the browser. You’ll hear these terms interchangeably. My Express Node.js server allows me to run Javascript code on the server-side, the back-end, outside the browser.

When it comes to security, any Javascript code in the client-side can be manipulated by the user, if they know how. That means any secrets (e.g. environment variables) you expose on the client-side can also be seen by someone who knows what they are doing. In short, client-side Javascript cannot be fully trusted. If you are passing your e-mail and password in client-side code then you might want to re-consider doing so. If your app calls an API endpoint to your server instead then the server-side code can run. The average user will not be able to manipulate the code running on the server-side and they won’t be able to see information you wanted hidden (e.g. email address and password). So, if you are concerned about security then it is best to carry out certain functions on the server-side and run appropriate validation on both client-side and server-side to ensure the data is good.

When it comes to performance, what I have in mind is what happens when your app first loads. Let’s consider our Create-React-App. We use Javascript to manipulate data and React takes the code into consideration and renders everything into HTML so it can be displayed in browsers. Create-React-App allows us to create Single Page Applications (SPA) which can look really good once it’s loaded. That’s the only caveat: “once it’s loaded”. If you have a particularly large app it takes time to render the HTML with the Javascript code but you must load it all before your app can be displayed in the browser. You may find this load time is barely noticeable but that depends on your app. The issue is with web crawlers; bots that go from website to website and analyse the content, tag everything and report their findings to search engines. Being robots they move quickly and sometimes they will move on from your site before the client-side rendering is complete and all they can report is a blank page. Not good for your SEO rating!

Instead of wholly relying on client-side rendering you can employ server-side rendering to avoid the issue with the blank page. This sounded like something I wanted to do as I didn’t like the idea of the blank page and missing out on SEO. There are ways to remedy this with Create-React-App but as I was doing my research another solution kept getting referenced that caught my attention and that was Next.js.

Lockdown coder: transformation from non-coder to coder in under 12 months…complete-ish.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store