Posts in React (6 found)
Dayvster 1 months ago

My Battle Tested React Hooks Are Now Open Source

## Don't yap just give me the links Ok I get it you're busy here you go: - [GitHub Repo](https://github.com/dayvster/react-kata) - [NPM Package](https://www.npmjs.com/package/react-kata) Have a great day! ## What's This? I've been developing react since 2013 it's been through a lot of changes and updates over the years. We've seen patterns come and go, however when hooks were introduced in 2019, I was instantly ... hooked. No wait please don't leave, that was a good joke and you know it! ![](https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExYjdtenpmZ2E1MnIwcTIxeGZ1cTV5OXQ1bGtobWN3am1wOTRkczlhbCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/28STqyG0HPzIQ/giphy.gif) Anyhow now that that's out of the way, I wanted to share with you a collection of various hooks that I have written over and over and over again in my past projects. These hooks have been battle tested in production applications and multiple client, personal and professional projects. ## Why Open Source? Well I have this post on my blog about why I believe everyone should open source their work, [Open Source Your Projects](https://dayvster.com/blog/open-source-your-projects/) I've been recently redesigning my website and fixing up my old blog posts and I stumbled upon this one decided to re-read it fully and discovered I am a hypocrite by value of pure laziness. Yes I did not open source these hooks sooner, because I was simply lazy. I had them in various different projects, repos, side projects etc. etc. But I never took the time to actually put them together in a single package and publish it. I just kept either navigating to these projects and constantly copy pasting them around OR worse yet I would rewrite them from scratch every time I needed them, which is just plain dumb. So I decided to stop being a hypocrite and finally open source a bunch of my stuff part of that was the task of collecting all of these react hooks and putting them together in a single package. So here it is ## Introducing React-Kata - [GitHub Repo](https://github.com/dayvster/react-kata) - [NPM Package](https://www.npmjs.com/package/react-kata) React-Kata is a collection of battle-tested React hooks that I've used in various projects over the years. These hooks are designed to make your life easier and help you write cleaner, more efficient code. ### Why React-Kata? Kata is a term used in martial arts to describe a set of movements and techniques that are practiced repeatedly to improve skill and mastery. Similarly, React-Kata is a collection of hooks that I've rewritten and reused and refined over and over again. So I thought it would be appropriate to name it React-Kata. Also I did martial arts as a younger person and wanted to show off a bit, lay off. ## Examples: - `useLocalStorage`: A hook that makes it easy to work with local storage in your React applications. - `useDebounce`: A hook that debounces a value, making it easier to work with user input and avoid unnecessary re-renders. - `useThrottle`: A hook that throttles a value, making it easier to work with user input and avoid unnecessary re-renders. - `useTimeout`: A hook that makes it easy to work with timeouts in your React applications. - `useInterval`: A hook that makes it easy to work with intervals in your React applications - `useSessionStorage`: A hook that makes it easy to work with session storage in your React applications. and many many more in fact to see a lot of all of them check out the [GitHub Repo Hooks overview](https://github.com/dayvster/react-kata?tab=readme-ov-file#-hooks-overview) ## Code Examples ### useShimmer This hook generates a shimmer effect SVG that can be used as a placeholder while content is loading. It takes width and height as parameters and returns an SVG string. ````tsx import { useShimmer } from 'react-kata'; function ShimmerDemo() { const shimmer = useShimmer(400, 300); return ; } ```` ### useWhyDidYouUpdate This hook helps you identify why a component re-rendered by logging the changed props to the console or handling them with a custom callback. I can not overstate how often this one has saved my ass in the past. ```tsx import React, { useState } from 'react'; import { useWhyDidYouUpdate } from 'react-kata'; function Demo(props) { // Logs changed props to console by default useWhyDidYouUpdate('Demo', props); // Or provide a callback to handle changes useWhyDidYouUpdate('Demo', props, changedProps => { // Custom handling, e.g. send to analytics alert('Changed: ' + JSON.stringify(changedProps)); }); return {props.value} ; } ``` ### useTheme Let's you simply manage themes in your application. Supports auto, light, dark, and custom themes. For custom themes you simply input the name of the theme and it will be applied as the data-theme attribute on the html element. It will also be stored in local storage and retrieved from local storage on page load. ```tsx import React from 'react'; import { useTheme } from 'react-kata'; function Demo() { // Supports auto, light, dark, and custom themes const [theme, setTheme, toggleTheme] = useTheme(["auto", "light", "dark", "solarized"]); return ( Current theme: {theme} Toggle Theme setTheme("solarized")}>Solarized setTheme("auto")}>Auto ); } ``` ### useReload Allows you to pass a custom condition that when met will trigger a page reload. ```tsx import React from 'react'; import { useReload } from 'react-kata'; function Demo() { // Only reload if user confirms const reload = useReload(() => window.confirm('Reload?')); return Reload Page ; } ``` ## Conclusion I hope you find these hooks as useful as I have. If you have any suggestions for new hooks or improvements to existing ones, please feel free to open an issue or submit a pull request on GitHub, I'll always appreciate feedback, criticism, suggestions and especially Pull Requests. Happy coding!

1 views
Loren Stewart 2 months ago

React Won by Default – And It's Killing Frontend Innovation

React-by-default has hidden costs. Here's a case for making deliberate choices to select the right framework for the job.

0 views
Cassidy Williams 2 months ago

I made a tree visualizer

I was going through some old folders on my laptop and found some old code from my old React Training teaching days for visualizing how component trees in React work, and turned it into its own standalone web app! Here’s the app, if you’re not in the mood to read more . Back when I was teaching React full time, one of my fellow teachers Brad made a tool that let you show a tree (like a data structure tree), and we would use it in our lectures to explain what prop drilling and context were, and how components could work together in React apps. I loved using the tool, and thought about some use cases for it when I found the old code, so I spruced it up a bit. It has some keyboard commands for usage: Most usefully (to me) is the ability to quickly make images for sharing them! The original code had each node maintain its own internal state and it was kind of recursive in how they rendered ( see exact lines here ). In retrospect, I probably should have changed it to be rendered with a big state tree at the top and serialized in the URL or local storage (kind of like what I did with PocketCal ), but eh, it works! See ya next time!

0 views
JSLegendDev 7 months ago

Learn React.js by Building a Game Search App | Part 3/3 - Finishing The App

In the previous part ( Here are links to part 1 and part 2 ), we finished setting up the logic to fetch data from our backend. Now it’s time to display the data in a nice looking UI. Creating The Game Card Component Conditional Rendering in React How to Render Lists in React Rendering a List of Game Cards Handling Edge Cases and Improving The User Experience Displaying Error Messages in The UI Adding a Loading Spinner Building The Game Details Component Creating a New API Endpoint to Fetch More Data Rendering The Game Details Component Creating The Screenshot Carousel After the user makes a search, we want to display a list of relevant games that will be rendered as a grid of cards where each card contains the game’s title, genres, cover image and the time it takes to complete the game if the data is available. The first step to achieve this is to build a reusable game card component. Inside the components folder, create a file called . Within that file, add the following code : We create a component with 5 props. : The link of the cover image. : The name of the game. : How long the game takes to beat. : An array containing the game’s genres. : A function that will run when the user clicks on a card. Let’s break down the JSX returned by the component. We the return a that acts as the card container. We set is as a flex container and make it relative so that within, we will be able to place the playtime indicator at the top-right of the card using absolute positioning. We then set the function passed as a prop to trigger when the container is clicked. We display the game’s cover using a simple tag. First, the image is set to take the full available width with . The height is set to 40 Tailwind units using . The Tailwind class is used to render the image in its original aspect ratio while still fitting within the width and height of the tag. stands for rounded medium and makes the corner of the image noticeably rounded. This tag is used to display the game’s name. We use conditional rendering to render the playtime indicator only if the playtime is above 0 hours. Usually, if it’s 0 then that means the playtime data for this game isn’t available. The RAWG API returns 0 in that case. Using absolute positioning we’re able to place the indicator at the top-right corner of the game card by using . There are many ways to achieve conditional rendering in React. Here are a few examples. First example with an if statement. Second example with a boolean expression. Third example, with a ternary operator. If you want to achieve conditional rendering within JSX you can’t use an if statement and are forced to use either a boolean expression or a ternary operator. Between using a boolean expression or a ternary operator in the example above, the latter is better since we display “B” in the case the condition is true and “A” otherwise. However, in our game card component we display the playtime indicator only if its value is above 0 and nothing otherwise. Therefore, the boolean expression is more fitting for our use case. Finally, we display the genres of the game. There can be more than one, that’s why we’re rendering this section as a list of items. Now has come the time to understand how lists are rendered in React. Note that the class is a custom class and you need to add it to your file for it to work. It often occurs when working on Web UIs that you want to render multiple elements at once. For example, you want to render a list of search results, in our case, a bunch of game cards. In React, you can achieve this by using the JavaScript function to iterate over an array and for each element return some JSX. At a basic level, it looks like this. However, there is something missing in the code above. When rendering multiple elements, the rendered JSX elements need to be assigned a key. This is to enable React to establish a relationship between array elements and the corresponding JSX element. This becomes very important if items of the list are later added or removed. The key enables React to make the correct updates to the DOM. You might come across React code using the index of the element as the key. This is to be avoided when the array can change later down the line. For example, if the elements of the array are sorted in a different order, the relationship between the index and the JSX element will be broken. To avoid this from happening, it’s usually best to use a consistent but unique key. Consistent in the sense that the key doesn’t change from render to render and unique so that no two elements in the list have the same key. In our example above, the only key that would best fulfill these two conditions are the lines themselves. If we assume that the data you want to display comes from a source that you control, you could have decided to assign a unique id for each item before sending the data to the client. For example, let’s assume that each line of our lines array will have an id. You would have something like this : You would use the id as the key. Alternatively, with destructuring you would do : For our genres, since the genre name is unique, we use the name for both the content of the list item and the key. Now that we have finished the game card component, let’s use it in to display relevant games when the search feature is used. Add the following code : Let’s break it down. We only render the game cards if the data is available. In that case, we first render a which acts as a container for all game cards and is going to be displayed as a CSS grid. : sets the as a grid container. : sets the grid to have 1 column only. : sets a gap of 5 units between each elements in the grid. : sets the number of columns of the grid to be 2 on smaller screens and beyond. is a media query in Tailwind. : sets the number of columns of the grid to be 3 on larger screens and beyond. is also a media query in Tailwind. We get the game cards data by doing which returns an array. We then map over it to render each game card. Before rendering a game card we make sure that the game has been added at least more than 30 times. The reason we’re doing this is that the RAWG API has the property which determines how much a game was added. It doesn’t specify what is exactly but I’ve noticed that if you just render what ever the array has you’ll often find yourself displaying cheap fangames and clones along side more legit titles. To show the best quality results as possible, I have figured out through testing that a game must have been added at least 30 times to be considered “legit”. As mentioned previously when rendering an array in React you must provide a key for each element. Here is no exception. However, you might be wondering if we have to define a prop called on the component before passing to it a key since it’s custom made and not a native JSX element? Fortunately, you don’t have to, it’s taken care of automatically by React. Since the RAWG API returns a slug for each game, this will act as our unique key since it never changes for a specific game and is unique. Now that we have added our game card list rendering logic, let’s test it out. Make sure to have your backend and frontend running with and respectively. You should have the following results. While we were able to successfully display relevant results when a user makes a query there are still edge cases we aren’t handling. For example, what should be shown to the user if there are no games relevant to what they searched for? In that case nothing is shown which isn’t a great user experience. To fix this, let’s add a message that will be displayed when no relevant search results are found. Modifiy the code we had previously like shown below. <></> is called a React fragment. This is useful when you don’t want to create an unnecessary to wrap two or more elements at the same level. In our case we want the JSX for the search results and the JSX for the “No games found!” message to be both children of the container having the className . There is no need to wrap them under an additional div. Now let’s test things out. As you can see, the message showed up. There’s still another edge case we haven’t taken into account. What if, for some reason, the app fails to retrieve data from the backend? Currently we show nothing in that case. However, the wise thing to do is to have some kind of error message displayed to the user. Since this error message is going to have the same structure as the one we used for the “No games found!” message, let’s create a reusable component in the folder. Create the file with the following code. Now, we can use this component in . Import the component at the top of the file. Then, replace the JSX we used for the “No games found!” message. Let’s use the same component to display an error message when the apps fail to retrieve the data from the backend. Now, when a network error occurs, you’ll get the following UI. Adding a Loading Spinner Another thing to improve upon is the fact that we give no indication to the user that the app is loading search results. Let’s add a spinner so that user doesn’t think the app has crashed. Under the folder create a file called and add the following code : This component is based upon the loading spinner example found here . Most of it is SVG code. I will not explain how SVG work because it’s out of the scope of this tutorial. Let’s just use that spinner as is in our app. In , add the following code : Then, modify our existing code where we display the search results : You’ll notice that we now have a ternary operator that determines whenever or not to show the spinner. If we aren’t in a loading state we render the grid or the error message. We use with the question mark as to only attempt to access the property of the object if it’s available. Now, let’s test it out. The final part of this project consists in building the game details component which is a component that will display a dedicated section for a specific game after having clicked on its game card. In a production app, you would probably use a router like React Router and make it display as its own separate page. However, I wanted to limit the use of third-party libraries, so I opted for displaying a component on the same page instead. Before we build that component, we need to write a new API endpoint in our backend to fetch data specific to a game. This endpoint will return a detailed description of the game. This wasn’t provided by the previous endpoint we had. In your backend, add the following endpoint to your file. The first API endpoint returns, amongst other things, the game’s slug which we can use to query this second endpoint by passing it as a param. Now restart the backend by doing and running the command . Then, in our frontend, in the file, add the following code : Finally, in the folder, create a new file called and add the following code. We started things simple, by writing the logic to fetch the relevant data as soon as the component is rendered. We pass two props to the component. which is an object that contains the data previously fetched for a specific game. It contains the game’s slug (which is its id), genres, title, etc… We use the slug to fetch more data (the game’s detailed description). The second prop is a function used to enable the user to go back to the search results if they wish to do so. Like mentioned earlier, in a production app, use something like React Router so that the user can use the back button of their browser to go back. This is called navigation and isn’t built into React by default, underlining the need for a third party library. Our backend will return a description of the game and is formatted as a single long string. If we render it as is, it will not look good in the UI. That’s why we need to add the following utility function. Place it above where the component is defined. Now that we have this, we can modify our component like so. We create a state variable for holding the description and use a second to split the game’s description into paragraphs as soon as the data is available. Let’s add more JSX but before, import the Spinner component we wrote previously. Let’s break it down. This is the button placed at the top of the component allowing user’s to go back to the search results if they wish to do so. You’ll notice that we’re using a custom class called . Add it to you file. Also, add the custom class which is used for displaying the various platforms the game can be played on as pill shaped blue “pills”. We then use a ternary operator, to show a loading spinner while we’re fetching the description data for the game. Once loading is completed, we render some JSX containing a banner with the game’s cover and name followed by the game’s description rendered in multiple paragraphs. Then, we will render a screenshot carousel that will be its own separate component (We will write the code for it later) and finally, we render the list of genres of the game and the various platform you can play it on. Additionally, we render a button that will open up a google page with a query to determine where the user can purchase the game. Before proceeding with the screenshot carousel component, let’s first try to render the component when a user clicks on a game card in the search results. Add the following code to . Then, in the of the GameCard components in add the following. Now, if you run the app (make sure to restart the backend and the frontend) you should have the following results. The last component of this project consists in a screenshot carousel. In the folder, create a file named and add the following code : Let’s break it down. We set a prop which will hold the array containing all screenshots of a given game. We first declared a state variable for holding the index of the current screenshot being displayed. We use a to preload all the screenshots. This is useful, so that when the user clicks on the arrow to look at the next image, they will see it instantly and won’t have to wait for it to load. We return a that acts as the screenshot carousel’s container. It has a background of , rounded corners with (stands for rounded large), takes the full width available of the parent element with , takes the full height but caps out at 96 units with and , prevents overflowing with and is set to relative so we can absolute position the arrows. Here, we added our two arrow buttons that allow the user to move back and forth. For both buttons their handlers updates the screenshot index properly by making sure that we don’t go out of the bounds of the screenshots array. Once the screenshot index is set, the carousel will re-render to display the correct image which is set here. The reason we have two tags, is that the first one will act as the background and will be blurred while the second tag displays the screenshot visible by the user. We use for the first tag, so that the image will take all the available space in the container and we use in the second image so that the image retain its aspect ratio. Therefore, the user will be able to see the full screenshot without having part of it cropped out. Finally, we have a span tag which will render as a top-right indicator of which screenshot you’re currently viewing. Now, that we have finished the carousel component, let’s add it in . First import the carousel at the top of the file. Then, replace this : Now, if you run the project, you should get the following. You have finished your first React project! I have not touched on deployment (there are many different ways to go about it and plenty of tutorials online) and other React topics but I hope this was a good introduction. Now that you have a basic foundation in React, you can start building your own projects and fill in your knowledge gaps using Google or taking a look at the official React docs . Subscribe so you don’t miss out on future posts and tutorials You might be interested in game development? You can check out this next. In the previous part ( Here are links to part 1 and part 2 ), we finished setting up the logic to fetch data from our backend. Now it’s time to display the data in a nice looking UI. Table of Contents Creating The Game Card Component Conditional Rendering in React How to Render Lists in React Rendering a List of Game Cards Handling Edge Cases and Improving The User Experience Displaying Error Messages in The UI Adding a Loading Spinner Building The Game Details Component Creating a New API Endpoint to Fetch More Data Rendering The Game Details Component Creating The Screenshot Carousel After the user makes a search, we want to display a list of relevant games that will be rendered as a grid of cards where each card contains the game’s title, genres, cover image and the time it takes to complete the game if the data is available. The first step to achieve this is to build a reusable game card component. Inside the components folder, create a file called . Within that file, add the following code : We create a component with 5 props. : The link of the cover image. : The name of the game. : How long the game takes to beat. : An array containing the game’s genres. : A function that will run when the user clicks on a card. : sets the as a grid container. : sets the grid to have 1 column only. : sets a gap of 5 units between each elements in the grid. : sets the number of columns of the grid to be 2 on smaller screens and beyond. is a media query in Tailwind. : sets the number of columns of the grid to be 3 on larger screens and beyond. is also a media query in Tailwind.

0 views
JSLegendDev 7 months ago

Learn React.js by Building a Game Search App | Part 2/3 - Building The Search Bar and Fetching Data From The Backend

Since we have mostly finished our setup in the previous part of this tutorial (You can read part 1 here ). We’re ready to start working on the search page of the app which is the main page of the application. In that page, the user should be able to use the search bar to search for a given game title or franchise and the app should call our backend which will call the RAWG API to retrieve a list of relevant games. Then, the app should display those games as cards containing a cover, a title, genres and how long it takes to beat the game if that data is available. Now that you know what we need to build, let’s get started. I’ll introduce relevant concepts as we go. Subscribe to not miss out when future parts of the tutorial are released! How is React Initialized in Our Project? What are React Components? React VS React-DOM Making Our First React Component Creating The Search Component What Are Props in React? What Are Hooks in React? The useState Hook Setting Our Backend to Enable Search Requests to The RAWG API Setting Up Express Defining The /api/games Route Fetching Search Data on The Frontend What is The useEffect Hook and How it Works? How is Data Fetched With useEffect? Creating a Custom Hook If you look at your folder, you should have the following files. Before we write any code, let’s remove the folder and the file. We don’t need these two. Since we’re using Tailwind, the only place we need for CSS is the file. Now let’s take a look at . For React to be used in a webpage, it needs to inject the content of your app within your HTML. To be more precise, we first need to create a root within your file from which your React app will be rendered. If you take a look at your file at the root of your project’s folder. You will notice the presence of a with an id of “root”. This was added automatically by Vite. Looking back at our React code : We can see that to inject our React app within the having the id “root” we pass that as a param of the function. It then creates an object that has a method called . We immediately call it to pass our main React component called wrapped under StrictMode (which adds useful behaviors to more easily find bugs). The component is the main building block when working in React. It allows you to build UIs in a modular fashion allowing you to reuse components in multiple places. It also allows you to manage complexity by placing logic specific to a component within it. At a basic level, a React component is just a JavaScript function that returns some JSX. Which, if you remember, is syntax that looks like HTML that you can write within JavaScript in a .jsx file. Here is an example! We have a React component that returns a containing an tag with the content “Hello World!”. You will surely notice that we defined this component by defining a function with its name’s first letter capitalized. The convention when defining React components is to use the PascalCase notation rather than the usual camelCase. Another thing that makes components really useful in React is that you can place React components within React components, enabling a modular approach to building UIs. Here’s another example. As you can see, to place a component within another you can use the self closing tag notation you’re used to from HTML along with the name of that component. Looking back at the import statements we had in . You’ll notice that we’re importing things from both and . You might be wondering why they are separate entities? React is the library that allows us to build UIs using reusable blocks called components that return JSX. React-DOM on the other hand is the one taking care of rendering React components on the DOM (Document Object Model) of the webpage. That’s why is imported from and not since it’s used to render to the DOM with the method. The reason for this split is that React can be used outside of the web. For example, it can be used for mobile development with React Native. Instead of the JSX being translated to HTML elements that are rendered on a webpage, they’re are translated to native mobile UI elements instead. In addition to React being used for mobile UIs, it can also be used to make pdfs with react-pdf . react-pdf in action Making Our First React Component Now that you understand how components work, let’s define our first component, the component. If you take a look at again, you’ll notice that we’re already importing this component from a file called . Let’s start from scratch by deleting everything in the existing file and adding the following code which will display the app’s name and logo. The tag will contain all of the content of the search page. We define it as a container with a direction set to . We then center the content within that tag along the cross axis of the container using . Below is a schematic displaying how the axis are defined according to the direction of the flex container. Remember that using will center the content of the flex container along the cross axis while will center its content along the main axis. We then make the tag take the full available width of the page using and give it a padding of 2 with . All of the styling explained above is succinctly described in Tailwind by passing the needed class names to the className property of the JSX element. Now, you might be wondering why is it instead of that you’re accustomed to in HTML? The reason is that there is a difference in how the attribute is named in HTML vs the DOM which the underlying model representing a webpage. Since React operates on the DOM it was chosen to use instead which is what the DOM uses. Now within the tag, we define a which will hold the app’s name and logo. This is set as a flex container with the direction set to by default, so we don’t need to specify it. We center its content along the cross axis so that the app’s title and logo are near each other at the center. We then use an tag to display the logo. You might have noticed that the path to the image does not contain the folder despite the image being in that folder. That’s because Vite will automatically make whatever is in the folder as if it was available from the root of the project, so you do not need to specify the folder in the path. Finally and sets the size of the logo using units defined by Tailwind which are responsive. If you now start a development server using the command in your terminal, you should get the following result. Let’s makes things prettier before moving on. In add the following Tailwind classes to the body tag. We’re setting the background color to be of gray-950 which is a color predefined by Tailwind that is near black. We then set the background image and set it to repeat so that it tiles indefinitely making the image cover the page regardless of the size of the viewport. You should have the following result. As you can see the app’s name near the logo is not visible. To fix the issue, let’s add a nice looking gradient to it. To showcase how you can create custom classes composed of Tailwind classes, let’s add the following in our file. The key here is to use the directive and then use the Tailwind classes you need. Creates the gradient. Makes sure the gradient is applied within the text’s letters. If you go back to our React component and apply the custom Tailwind class we created along with a few other Tailwind classes, you should get the following result. Creating The Search Component In the previous section we created our main React component acting as the entrypoint of our UI. However, we need to define more than just one component in our app. To keep things organized, let’s create a folder under the folder. Within, let’s define our next component, the component by creating a file. Add the following code in . The component is essentially a search bar. You’ll probably notice that we have params that are passed to this component. These are called props. It’s another one of React’s major concepts. What makes components flexible in React is the ability to pass props to them to change how they’re rendered. This makes components usable in more than just one screen or one place in the app. You can view props the same way as params that you pass to a function. Here is a basic example of how props are used in React. To pass props to a component you can simply start adding arbitrary attributes to where you call this component. In the example above, I decided to use an attribute called “name” that is then available under the props object where the component is defined. That’s why I can do and get access to “Hello World”. You might have noticed that we use curly braces when putting prop.name within the tag. This is important, so that the actual value, “Hello World” is what’s rendered rather than having literally “prop.name” displayed. A more convenient way of dealing with props is to use destructuring which is a JavaScript concept allowing us to directly get the properties we need. So now, if I need more than one prop, I can do the following. Now that you understand what props are and how they work, let’s further analyze the code for the component. Most of the Tailwind classes here are easy to understand if you already know CSS so I will not go over each of them. I would like however, to explain a few that may not be as straightforward to figure out : : Applies 4 units to the bottom margin of the element. If you had instead, it would be applied for margin left, for margin right, etc… : Applies 2 units to both the top and bottom margin of the element. Therefore, along the y axis. If you where to use , the left and right margins would be increased instead since they’re along the x axis. Now let’s take a look at the input element. In React, the input attribute has two properties that are very useful. The attribute allowing us to set the value inside the field. The attribute which takes a function and will run it every time the user types in the field. Which also allows us the get what was typed. We pass to these two attributes the and props we defined for the component. Now, go back to and add the following code. What is this function we’re using? It’s called a hook and hooks are another one of React’s major concepts. Hooks let you use different React features from your components. You can either use the built-in hooks or combine them to build your own. Here in particular, we’re using a state hook to set a state variable with the goal of holding the user’s search query and to update the UI when it changes. From React’s docs, the usefulness of the hook is made apparent. To update a component with new data, two things need to happen: Retain the data between renders. Trigger React to render the component with new data (re-rendering). Creating a state variable using the useState hook allows us to achieve both. A state variable to retain the data between renders. A state setter function to update the variable and trigger React to render the component again. In our case, is the state variable and is the state setter function. Finally, we pass within the default state value we want to use. When creating a state variable here is the convention that is usually adopted. What makes React convenient for building UIs rather than using vanilla JS is that you don’t need to manual update the UI by changing the content of various HTML nodes. As we saw above, by using a state variable, React will take care of updating the UI automatically when the state variable changes. By passing an function that calls the state setter function and passing to it the value of what was typed using , we update the state variable. Since we’re also passing the state variable to the component, React will re-render the component everytime it’s changed. You should get the following result. We could have defined the state variable within the component but it’s better to do it in the component instead. This is a better approach because we need to have access to so that we can pass it to our backend and make the RAWG API call to get relevant search results. Now that the search bar is completed, let’s do some backend work to be able to query the RAWG API so it can provide the data we need. In your backend repo, add the following code to your file. We first import all the needed packages. I explained why we needed each of them in part 1 of this tutorial. Refer to it here . We then call to load our environment variables. We can then access them using We intialize the express web framework which is the core of our backend and pass it to a const called . We then set our CORS (stands for Cross Origin Resource Sharing) options which allows us to only authorized requests coming from the domain of our frontend. One thing to know about CORS is that it’s only enforced through the web browser. That means, a mobile app could still make requests to our backend despite the options we set. Learn more about CORS here . Using , we apply the CORS options to our Express app. Finally we set up our rate limiter preventing potential DDoS attacks where a client makes too many requests in order to take down our backend. To make our backend actually do something let’s add the following code. We define our first route that the client will be able to call and then make the Express app run by using . We want this route to return a list of games that matches the query passed by the client. In Express, a route is defined this way. Here we’re using a GET route since we’re not modifying a resource, we’re just requesting it. The first param is the route path we want to use, while the second param contains the function that’s going to run when the request is made. will contain the query of the client. Clientside, the query will be passed as a param to the route path. Here’s an example. Will result in containing . Now let’s continue by filling out the logic for the route. Let’s break it down. By using object destructuring we rename the param to . We do this because the RAWG API expect a search param and it would look weird to do : However, this is just a matter of personal preference. You can decide to stick with if you want. Within the Try/Catch statement we make the call to the RAWG API passing our API key from our environment variables. Something to note is that the RAWG API expects you to pass the API key as a param rather than putting it in the header like other APIs. Also, in Node.js you can’t use fetch by default as you can on the frontend. That’s why we had to install the node-fetch package. The rest of the code is pretty standard error handling. Either way, we always end up returning json with either an error message or the data the client requested. Finally, remember to run the backend using the following command : Now that we have created the backend route we needed, let’s head back to our frontend to write the logic allowing us to fetch the relevant data according to what query the user entered in the search bar. We need to first talk about another very important hook in React called . To put it simply, it’s a hook that lets you synchronize a component with an external system. In our case it’s going to be our backend. In practice, it’s a function that’s called within a component and takes usually two params. The first is the function you want to run which is your “effect” and the other is a dependency array. It will run after the component is first rendered and every time a dependency in its dependency array changes. Above is an example of how we use . We have an empty dependency array meaning that the effect will run only after the component renders the first time. This occurs once in prod but twice in development because we wrapped our app with . You can use without a dependency array but it will run after every render. In the example above, we fetch and display a new quote from a fictitious API when the user clicks on a button. You’ll notice that the dependency array of our has the state variable. This means that the hook will run once after the component is rendered the first time (twice in dev because of StrictMode) and then every time is modified. In practice, if you design your app in a way that you need the user to click a button to make an API call, you do not need to use as you could put the fetching logic within a function you pass to the button’s handler. The example above was just to demonstrate at a basic level how this hook works. In our app’s case, its usage is warranted since we need to make an API call when the user finishes typing something rather than clicking a button. While using this hook like shown above is ok for toy examples, in practice when dealing with APIs, I would recommend using a library like Tanstack Query formerly known as React Query which makes fetching, caching, synchronizing and updating server state a breeze. I recommend this part of the React docs regarding . Oftentimes, you might be tempted to use it while it’s not necessary. The docs provide helpful guidance regarding this hook. In our app, we will still use but also create our own hook to deal with loading states (what to show the user while we’re fetching data) and error handling. While React offers hooks like and , nothing prevents you from creating your own hook. This is what we’re going to do now. Our hook is going to be called and will be responsible for fetching the data we need from our backend and dealing with loading states and errors if they occur. Create a new folder called within the folder and within a file called . In the file you just created, add the following code : will expect a fetch function which will contain the API call and pass it to its own function and set the appropriate loading or error states depending ont the situation. The hook returns the data, the loading state, the error state, the fetchData function to fetch data again if needed and finally, a reset function to reset the state if needed. Let’s create the fetch function specific to getting the list of games related to a search query. For this purpose, let’s create file called within the folder. In it, add the following code. For the code above to work we need to define an environment variable in our frontend. This is done just to make it easy to swap in and out the domain of the backend as needed and not for security reasons. Create at the root of your project a file containing the domain of our backend. Now, we can go to where we will write the logic to fetch the needed data when the user enters a query in the search bar. Let’s break it down. We call and pass to it an anonymous function that will call our function created in the file and pass to it the user’s search query. The reason we’re wrapping it in a function is that we don’t want to call immediately but rather let call it in its function. We also couldn’t pass it on its own because we wouldn’t be able to pass the search query param along. Once called, the hook will return all that we need to display the relevant UI depending on the situation. Next, we have our . We set a timeout of 500ms as to provide enough time after the user has typed before making a request otherwise we would be making a call every time a letter changes which would be wasteful. This is called debouncing. Then, we have an if statement with a call to trim() that removes any whitespace at the beginning and end of a string. If the user didn’t type anything yet or just uses spaces in the search bar, an empty string will be returned which is falsy in JavaScript. Therefore, no API call will be made. Since will run after the component first renders, in that case the search bar would be empty, we wouldn’t want to make an API call after all. The function we pass to returns a function that clears the timeout we just created. This is called a cleanup function and is optional when using this hook but needed in our case. This is so we can avoid memory leaks. If we were to not use one here, every time the hook runs, we would create a new timer that would never be deleted. That’s about it. The logic for fetching data is done. To make sure that it actually works, let’s the data fetched. Below the we just added, create another one with the following content. (Yes, you can have more than one per component.) Make sure to re-run both the frontend with and the backend with . Now, if you try using the app. You should get the following result. In the last part of this tutorial, we will write the logic to display the search results in nice looking game card components and then work on displaying more details when the user clicks on a specific card. Subscribe for more interesting tutorials! UPDATE : Part 3 is now available! Since we have mostly finished our setup in the previous part of this tutorial (You can read part 1 here ). We’re ready to start working on the search page of the app which is the main page of the application. In that page, the user should be able to use the search bar to search for a given game title or franchise and the app should call our backend which will call the RAWG API to retrieve a list of relevant games. Then, the app should display those games as cards containing a cover, a title, genres and how long it takes to beat the game if that data is available. Now that you know what we need to build, let’s get started. I’ll introduce relevant concepts as we go. Subscribe to not miss out when future parts of the tutorial are released! Table of Contents How is React Initialized in Our Project? What are React Components? React VS React-DOM Making Our First React Component Creating The Search Component What Are Props in React? What Are Hooks in React? The useState Hook Setting Our Backend to Enable Search Requests to The RAWG API Setting Up Express Defining The /api/games Route Fetching Search Data on The Frontend What is The useEffect Hook and How it Works? How is Data Fetched With useEffect? Creating a Custom Hook react-pdf in action Making Our First React Component Now that you understand how components work, let’s define our first component, the component. If you take a look at again, you’ll notice that we’re already importing this component from a file called . Let’s start from scratch by deleting everything in the existing file and adding the following code which will display the app’s name and logo. The tag will contain all of the content of the search page. We define it as a container with a direction set to . We then center the content within that tag along the cross axis of the container using . Below is a schematic displaying how the axis are defined according to the direction of the flex container. Remember that using will center the content of the flex container along the cross axis while will center its content along the main axis. We then make the tag take the full available width of the page using and give it a padding of 2 with . All of the styling explained above is succinctly described in Tailwind by passing the needed class names to the className property of the JSX element. Now, you might be wondering why is it instead of that you’re accustomed to in HTML? The reason is that there is a difference in how the attribute is named in HTML vs the DOM which the underlying model representing a webpage. Since React operates on the DOM it was chosen to use instead which is what the DOM uses. Now within the tag, we define a which will hold the app’s name and logo. This is set as a flex container with the direction set to by default, so we don’t need to specify it. We center its content along the cross axis so that the app’s title and logo are near each other at the center. We then use an tag to display the logo. You might have noticed that the path to the image does not contain the folder despite the image being in that folder. That’s because Vite will automatically make whatever is in the folder as if it was available from the root of the project, so you do not need to specify the folder in the path. Finally and sets the size of the logo using units defined by Tailwind which are responsive. If you now start a development server using the command in your terminal, you should get the following result. Let’s makes things prettier before moving on. In add the following Tailwind classes to the body tag. We’re setting the background color to be of gray-950 which is a color predefined by Tailwind that is near black. We then set the background image and set it to repeat so that it tiles indefinitely making the image cover the page regardless of the size of the viewport. You should have the following result. As you can see the app’s name near the logo is not visible. To fix the issue, let’s add a nice looking gradient to it. To showcase how you can create custom classes composed of Tailwind classes, let’s add the following in our file. The key here is to use the directive and then use the Tailwind classes you need. Creates the gradient. Makes sure the gradient is applied within the text’s letters. If you go back to our React component and apply the custom Tailwind class we created along with a few other Tailwind classes, you should get the following result. Creating The Search Component In the previous section we created our main React component acting as the entrypoint of our UI. However, we need to define more than just one component in our app. To keep things organized, let’s create a folder under the folder. Within, let’s define our next component, the component by creating a file. Add the following code in . The component is essentially a search bar. You’ll probably notice that we have params that are passed to this component. These are called props. It’s another one of React’s major concepts. What Are Props in React? What makes components flexible in React is the ability to pass props to them to change how they’re rendered. This makes components usable in more than just one screen or one place in the app. You can view props the same way as params that you pass to a function. Here is a basic example of how props are used in React. To pass props to a component you can simply start adding arbitrary attributes to where you call this component. In the example above, I decided to use an attribute called “name” that is then available under the props object where the component is defined. That’s why I can do and get access to “Hello World”. You might have noticed that we use curly braces when putting prop.name within the tag. This is important, so that the actual value, “Hello World” is what’s rendered rather than having literally “prop.name” displayed. A more convenient way of dealing with props is to use destructuring which is a JavaScript concept allowing us to directly get the properties we need. So now, if I need more than one prop, I can do the following. Now that you understand what props are and how they work, let’s further analyze the code for the component. Most of the Tailwind classes here are easy to understand if you already know CSS so I will not go over each of them. I would like however, to explain a few that may not be as straightforward to figure out : : Applies 4 units to the bottom margin of the element. If you had instead, it would be applied for margin left, for margin right, etc… : Applies 2 units to both the top and bottom margin of the element. Therefore, along the y axis. If you where to use , the left and right margins would be increased instead since they’re along the x axis. The attribute allowing us to set the value inside the field. The attribute which takes a function and will run it every time the user types in the field. Which also allows us the get what was typed. Retain the data between renders. Trigger React to render the component with new data (re-rendering). A state variable to retain the data between renders. A state setter function to update the variable and trigger React to render the component again.

0 views
David Dodda 1 years ago

Cool Btn Hover Animation! (react)

IDK, just some cool btn hover animation. yoinked it from stream elements landing page.

0 views