Tutorials on Hooks

Learn about Hooks from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

How to Use useCallback Hook with TypeScript

The useCallback hook returns a memoized callback that only changes if one of the dependencies has changed. This helps us to avoid unwanted and unnecessary components re-renders. The basic syntax for the useCallback hook is: You don't need any additional typings since TypeScript knows that useCallback accepts a function and an array of dependencies. It is preferable to use eslint-plugin-react-hooks though, to ensure you don't miss any argument in the dependencies array but that's optional. Let's assume we have a login form component: And then we have 2 input components: The problem is that when we change an email React will re-render both inputs instead of only EmailInput . This is happening because handler functions are being created on every re-render of the LoginForm component. So, on each render there are new handler functions for the InputEmail and PasswordEmail component, that's why they re-render each time. Let's fix that! Now, when we change an email or a password only the corresponding input component re-renders.

React Carousel: Building the Component from Scratch vs. Using a Library

In this tutorial, I'll show you how to create a simple React carousel from scratch, using hooks, and how to build the component using the React-slick library. When you start a new React project, it's tempting to build your entire UI library from scratch, as you have all the freedom in the world to create the components however you like them and to structure your code in a way that makes sense for the team. Yet, using a library seems like a better option when you need to deliver faster. You can still customize the components and most of the work is already done, so if you're not bothered by the generic look, you can copy-paste the code and you're ready to go. I won't detail all the pros and cons of using libraries, but as a general principle, if you're concerned with the size of your bundle, dislike the bland design of ready-made components, or you anticipate frequent changes in design due to stakeholder requests, for example, it's better to build your own components. So in this tutorial, we'll explore both options: first, we'll build a React carousel from scratch, then we'll create a separate slider component using one of the popular libraries. By the end of this post, you will know how to create a basic React carousel component using hooks, and how to use an out-of-the-box slider component with the React-slick library. As this tutorial doesn't cover the basics of React, to make the most of it, you should already be familiar with: We'll build our component in a React sandbox, so go ahead and create a new project, then add styled components as a dependency.  Since we’re building the slider from scratch, we’ll have at least two separate components: one for the slider, and one for the images. So let’s go ahead and create a new folder under src , for the components. Your project structure should look like below. Our main component, the carousel, will be imported in the App.js file, which will look like this: The images will be stored in an array, and passed as props. Next, let's get some images to display in the carousel. I want to use some kitty pictures from Unsplash, but I don't want to store them in a separate folder inside the project. Instead, I want to use the API, so I need the GET endpoint, which looks like this: https://api.unsplash.com/search/photos?query=cats&client_id= To be able to use this endpoint you'll have to create a dev account on Unsplash , so go ahead and do that first. We won't expose the client ID here, so no need to worry about that. Create your dev account here Next, add your client ID to the query to retrieve some kitty images. I'll get 4 images and add the URLs to the ImageData array, as follows: Here I'm using the raw images, but you can get them in different sizes if you prefer. Check the documentation here for more options. So the final App.js file looks like this: Now we can create the image component. Let’s add a new file under components , and call it SlideImage.js . I'll use styled components as I find it more convenient. We can start building the final slider component. Let’s create a separate file called Slider.js , and import these two.   So let's see what's happening in this component. First, I've added another library for some icons, so that we can add arrows on the sides. The library used here is react-icons , but you can use whatever you prefer, or build your own arrows. Then, I've added some styling in the styles.css file for the arrows, to position them: Now we have the arrows, but we need the slides to move when we click them. So we'll use the useState hook to set the current index of the images, and move to the previous or next slide when the arrows are clicked. I'll explain this part separately. So first we're declaring a new state variable, which is "current" in our case, as we want it to define the index of the current slide. Then, we're defining the functions that will change the state: nextSlide and prevSlide . When the left arrow is clicked, the prevSlide function is called, and what this function does is check the index of the current slide, the subtract one, to display to the previous slide. In the same manner, the nextSlide function checks the index of the current image and adds one, unless the current index is 3, which means that the image is the last one in the carousel. Don't forget that the indexes for the ImageData array start at 0, so the current index 3 actually means that we're referring to the 4th image of the slider, which is the last one. So in this case, the next image to display will be the one with index 0. That's it, you should now have a functional carousel that looks like this: You can see the final code here . For the second part of this tutorial, I’ll use the React-slick library for building the carousel component. Let's go ahead and create a new sandbox, and add react-slick and slick-carousel as dependencies. Your project structure should look like this.  To make use of the CSS that this library comes with, you’ll have to import the styles. For this tutorial, I’ll import them directly in the styles.css file:  We’ll build the carousel directly in the App.js file, so let’s import from the Slider from the library and start building the component:  I've added an empty array for the images that I want to include in the carousel, so we can use the .map method later on and display them one by one. We'll get back to this array in a few minutes, but first, let's solve the styling.   As you can see above, there are some classes in the slider, so let's now define them in the styles.css file: Now let's go back to the carousel images. Update the images array as follows: I've downloaded some pictures from Unsplash, and added them in the src folder, in a dedicated images folder. Now I'll import them in the App.js file: And now let's finalize the carousel code: The image URL, alt text, and name are now passed as props. A few words on the settings of the carousel: Dots and infinite are set to true , which just means that the dots are displayed under the carousel, and the images are displayed in an infinite loop. The slidesToShow property determines how many images the user sees in one frame, and the slidesToScroll determines how many images you can scroll at once. The speed property defines the animation speed in milliseconds and the className adds the styling for the slides. If, for example, you want the slider to be displayed vertically instead of horizontally, you can easily do this by adding the vertical property and setting it to true . I'll adjust the styling of the carousel a bit, to center the pictures and titles. Here's the updated code: Your carousel with React-slick should look like this: If you want to display a single picture at once, change the slidesToShow value to 1 instead of 2. Also, to display arrows as we did in the previous carousel, you'll need to do some adjustments to the CSS. So in the styles.css file, adjust the code as follows: Now you'll have a carousel that looks more like the previous one. You can find the project sandbox here . As you can see, the second option - using a library - is much faster and quite straightforward. Thus, if you need to build a React carousel component in a short time and you're not too worried about bundle size or design variations, using the React-slick library is more efficient. You can see a more detailed tutorial on React-slick here , or continue learning React in a more structured manner with the Fullstack React book .

Thumbnail Image of Tutorial React Carousel: Building the Component from Scratch vs. Using a Library

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

How to Handle Effects Using Hooks in React with TypeScript

There are 2 hooks to handle side-effects in React: The first one fires after layout and paint, during a deferred event. The second one works synchronously before the next paint, and used to handle effects that are visible to a user. The useEffect hook accepts 2 arguments: By default, useEffect fires on every re-render. If you need it to fire only when certain values change use the second argument to point out those values. You can also return from an effect a clean-up function. The clean-up function runs before the component is removed from the UI to prevent memory leaks. You don't need any additional typings for the useEffect hook. However, TypeScript knows about its inner structure and type signatures, so there is no chance to compile something like: This hook is the same in a sense of type signatures as the useEffect hook. So you can re-write a counter component using it: It also doesn't require any additional typings.

How to Use useReducer with TypeScript

The useReducer hook is a hook that allows you to create a state, update it, and share its data across different components. (Its core logic is similar to Redux .) It takes a reducer-function and an initial state as arguments and returns a tuple of a new state and a dispatch function. The reducer must extend the Reducer<State, Action> type, which is a function that takes a state and an action as arguments, updates the state, and returns the updated state: A state is usually an object with some data. Let's use a counter as an example. If we want to keep track of a current counter value, we can create an object with a value field: We will use this State type as a type parameter for the Reducer type later, and the initialState object will be the default value for the state. An action is sort of like an event, which triggers the state updates. For example, a counter can have 2 actions: for increasing and decreasing its value. Usually, an action is an object that has a type and payload . The type is like an ID of this action, and a payload is a data that the action transfers. Now that we have a state and a set of actions we can create a reducer. When a reducer is ready, we can use the useReducer hook. Now we combine our initial state, reducer, and actions with a component:

How to Use React Refs with TypeScript

Refs provide a way to access DOM nodes or React elements created in the render method. Also, they can be used to store some references to entities or objects for accessing them later. To use refs with functional components use a special useRef hook . It is a generic function, so we can pass a type-parameter, that will tell TypeScript what type is acceptable for this ref. Initially, we set a ref's value as null , because it will be set later on render. That's why we need to null-check inputRef.current later in onFocus . Also, inputRef itself is an object that contains a value in the current field. So to access the real element we need to get a value of this field. In class components, you can store refs in private class fields after creating them with createRef . When you need to access some data but you don't need to share it across components and don't need to change it you can use refs too.

How to Use React Context with TypeScript

React Context provides a way to pass data through the component tree without having to pass props down manually at every level. Use it when you need to share data “globally”, between many components on different levels to a component tree. To create a context use React.createContext : With TypeScript, you can declare a type for a context , so that TypeScript will know what types are acceptable for this context. However, there is a catch. If we have a data structure that can't have default values we can't just type a context: There are 2 workarounds here. The first one allows not to assign values to fields of a User type. So when we pass a defaultUser as an initial value there no errors: But in this case, we lose in type-safety a bit because we can miss some values later. The second option is to set null as an initial value: This way we don't lose in type-safety, but we will need to check if the context value is null every time we access it. When created, a context can be used in components. To give access to a context value we need to use Provider : The Provider component accepts a value prop to be passed to consuming components that are descendants of this Provider . To get a value we need to use the Consumer component: It uses a render-prop pattern . This means that it accepts a function instead of a component as a child. It will then pass a context value as an argument to this function. You can also use useContext hook to get access to a context value. This makes the component's source much simpler and cleaner.

How to Use State in React Components with TypeScript

When you need to store some data that won't be shared across components you can use the local component state. To use state in functional component use useState hook. This hook returns a tuple of two values. The first one is the current value of the state, the second one is a function to update the state. You can also increase type-safety declaring what types a state accepts: In class components, you can define a state as a class property called state . With TypeScript, you can declare a type for the state: The CounterProps type is used to declare what type the properties of this component support. The CounterState type will check the state types at the pre-compile time, so you will know earlier if there is an error. You don't have to annotate CounterState the second time inside of a component itself, but it allows better type inference when accessing this.state. Notice the React.Component<CounterProps, CounterState> type. This is the generic React.Component type. It takes two type-parameters that tell TypeScript how to interpret types of component props and state, so TypeScript can derive types of each field in props and the state. There is no need to mark types fields readonly since React.Component<P,S> already marks them as immutable. To change state in a class component use the setState method . This method enqueues changes in the state and causes a component to re-render.

A journey through the implementation of the useState hook

When the React team released hooks last year, my first thoughts were, "what new piece of wizardry is this which has been unleashed upon us?!". Your initial impressions may have been less dramatic but I am sure you shared my sentiments. Digging into the implementation of new framework features is one of my favoured methods of understanding them better, so in this post I will attempt to walk you through part of the workflow that is triggered when the useState hook is used. Unlike other articles which teach you how to use a hook or implement your own version, I am more concerned with the code behind the hook, so to speak. One way I like to break down features is by focusing on their underlying data structures. Components, hooks, context...all these are React features but when you peel back the layers, what are they really? I find this approach immensely useful because it helps me not to be fixated on framework specific concepts but on the tool used to build the framework - JavaScript. The first thing we will do is create a very simple example application (they work best for this kind of deep dive): Our app renders a button which displays a counter and increases it by one it whenever it is clicked. It consists of a solitary function component. Hooks were created to encapsulate side effects and stateful behaviour in such components. If we look at this code through our data structure lens, we can see that: Before we go into what happens next, let us remind ourselves of some of the behaviour we expect to see based on how hooks work: All code taken from React's source is from version 16.12.0 React hooks are stored in a shared ReactCurrentDispatcher object which is first initialised here when the app loads. It has one property called current , which has null as its initial value, and is allocated hook functions corresponding to React's mount or update phase. This allocation happens in the renderWithHooks function: In the source, there are comments above this code which explain that if the following check nextCurrentHook === null is true, this indicates to React that it is in the mount phase. You might be interested to know that the only difference between the dev and production versions of the HooksDispatcher objects is that the dev hooks contain sanity checks such as ensuring that the second argument for hooks like useCallback or useEffect is an array. At the beginning of our app's lifecycle, our dispatcher object is HooksDispatcherOnMountInDEV . Each time a hook is called, our dispatcher is resolved by this function which checks that we are not trying to call a hook outside of a function component. useState itself actually calls a function called mountState to execute the core of its work: mountWorkInProgressHook returns an object which starts off with null as the value for all its properties but ends up like this at the end of the function: In mountWorkInProgressHook we see that return [hook.memoizedState, dispatch] maps to our state initialisation expression const [count, setCount] = React.useState(0) . With regards to the hooks part of React's initialisation, this is where our interest ends. At the beginning of this article we said we would be looking at things from a data structure perspective. React exposes hooks to us as functions but under the hood, they are modelled as objects. Why this is the case will become apparent in the next section. What happens when we click the button and update our counter? From what we know so far, we should expect the answer to that question to also include answers to these sub-questions: The answer to question two is comes from the declaration of dispatchAction . Its expected arguments are dispatchAction(fiber, queue, action) . In the mountState function we can see that fiber and queue are already passed in, so action refers to whatever argument we pass to setCount . This makes sense since dispatchAction is bound function . The argument fiber in dispatchAction provides the answer to question three. I have written about React's new fiber implementation here but essentially, a fiber is an object that is mutable, holds component state and represents the DOM. React creates a tree of these objects and that is how it models the entire DOM. Every component has a corresponding fiber object. You can actually view the fiber node associated with any HTML element by grabbing a reference to the DOM element and then looking for a property that begins with __reactInternalInstance . The fiber object we get when dispatchAction is for our ComponentWithHook component. It has a property called memoizedState and its value is the hook object created during mountState 's execution. That object has a property called next with the value null . If ComponentWithHook had been written like this: Then memoizedState on its fiber object would be: Hooks are stored according to their calling order in a linked list on the fiber object. This order is why one of the rules of using hooks is they should not be used in loops, conditions or nested functions. For example, the docs provide the following code to illustrate what could go wrong: When React first initialises the app, the fiber node for this component has a property called _debugHookTypes with the following array ["useState", "useEffect", "useState", "useEffect"] . When setName is invoked, maybe to clear the name field in the form for instance, the updateHookTypesDev function runs and compares the currently executing hook and its expected index in the array. In the example above, it finds useState instead of useEffect and throws an error. But what if you tried tricking React by writing this: You will be caught in the renderWithHooks function thanks to the linked list implementation. When the error occurs, React is expecting to be working on useState('Poppins') and for the next property on its hook object to be null . However, in the example above, it encounters the useState('Nyasha') hook instead and find its next property pointing to the hook object for useState('Poppins') . Moving on to our first question (which state field on the hook object gets updated?), we can answer it by looking at the hook object we get once the component has been updated and re-rendered: A lot has changed. The most significant being queue.last and baseUpdate . Their changes are identical because baseUpdate contains the most recent action that changed baseState . If you were to increment the counter again and pause at the updateFunctionComponent , for example, the action property on queue.last would be 2 but remain as 1 on baseUpdate . The explanation for queue.last 's changes are as follows: Because it accepts a function which will take the current state as its first argument, we could re-write our setCount function like this: Some developers advocate giving a function to useState's update function if your state update depends on your previous state. Another thing to note is that if the newly computed state is the same as the current state, React bails out without scheduling a re-render. I came across many references to reducers whilst looking at useState and this is because the function which actually does the state update is called updateReducer . It is also used to perform updates by the useReducer hook. As I said earlier, if last.eagerState is computed, it means React has not yet entered the render phase. When it eventually does so, it realises that the new state has already been "eagerly computed", so it is applied to the lastRenderedState , memoizedState and baseState properties. We began this article by asking what happens when we introduce the useState hook to a codebase. It involves the creation of a shared object and a linked list. This post is by no means an exhaustive or complete explanation of useState but I hope it has provided some interesting insight into React's internals. As I mentioned at the outset, focusing on the data structures behind library and framework features can yield some interesting learnings. From a developer's point of view, hooks are functions which encapsulate stateful code and side effects but internally, React is working on a linked list. I have found this approach not only educational but empowering because it reminds me that despite the complexity of the tools we use, they are built using some of the JavaScript language features you and I use daily.

Testing Custom React Hooks with Jest

Hooks in React are a new, popular, and extensible way to organize side-effects and statefulness in React components. By composing the base hooks provided by React, developers can build their own custom hooks for use by others. Redux, ApolloClient, and Callstack have distributed custom hooks to access your app's store, client, and themes using the useContext hook. You can also compose useEffect and useState to wrap API requests or wrap the concept of time. It's powerful. It's simple. These two statements are not a coincidence, either: the power is the simplicity. The same goes for testing custom React hooks. By the end of this write-up, you'll think testing hooks as simple, too. We'll learn about React hooks, React in general, some basics of unit testing, and the bigger picture when it comes to automated testing. Don't panic, it's all right here in GitHub . Give the repo a star before cloning. React hooks are not quite normal functions. They need to run in a React render context, otherwise, they will give you an annoying error. Other literature on this topic suggests building a React component in the test and hacking that to test your hook's functionality using component testing tools like Enzyme. I found this approach to be brittle (who wants to maintain an unused component for every hook change?) and unnecessary. Try using the react-hooks-testing-library . It makes testing React hook behavior, parameters, and return values a breeze. Much easier than dealing with Enzyme, for example. Key concepts are the renderHook and act utilities. The first is where to specify your React Hook, context, and parameters. For instance, here is how to set up and test a React hook's parameters and return value. The act utility is for triggering side-effects for your hook to respond, like events or changing props. It is the same as the act provided by React . We'll see it in action later when we learn (spoiler alert) time control. Mocking is like the beginning of an Indiana Jones movie. It's like filling a bag with sand so when we swap the sandbag with the treasure, the detector doesn't trigger the trap. The detector has to not see the difference between the mock and the real thing. For example, you can mock axios so your hook does all the steps to send an HTTP request without actually sending a request. Plus, because you control the mock of axios , you can decide when the promise resolves or rejects. In React, dependencies can be your package.json dependencies or the exports of other source modules through import/requires, provided through context, or defined elsewhere in the file. If your hook depends on it in order to work, then it's a depend ency. When it comes to testing anything, from a web application to - yes - a React hook, there are different levels at which we can test. The core question of automated testing is this: how much should we mock? If we mock too many dependencies, we lose confidence that the system works as a whole. However, if we mock too few, the sheer number of moving parts cause our tests to be slower, less reliable, and harder to debug/pinpoint failures. If you want to learn more about managing software quality and automated testing, check out these 2014 slides from Google engineering. The prevailing wisdom is to have more small tests with mocks and a few large and valuable end-to-end tests. This is often visualized using a pyramid, called the "testing pyramid". In essence, most of your tests should mock a lot (unit tests), then some tests should mock less and ensure lower-level units are wired up together properly (integration tests), and then fewer tests mock even less and ensure the mid-size units interact properly (also integration tests). At the top of the pyramid, tests should have no mocks yet be very few in number (end-to-end tests). To use another analogy: if you were testing a car, you would test if the sparkplug works, then make sure the assembled piston works after testing its parts, then make sure the engine works after testing its parts, then make sure the whole car starts and survives a lap around the track after testing the gearbox, chassis, brakes, etc. Your hooks rely on dependencies to get almost anything done. Maybe your hook reads state from a Redux store, or perhaps your hook triggers HTTP requests or GraphQL queries. When unit testing React hooks, you want to avoid depending on anything outside of your UI code, like backend or browser APIs. That way, your tests failing means the problem is with the UI and not somewhere else. Test frameworks give the ability to create mock functions. I find the Sinon.js documentation for stubs (same idea, different terminology) does a nice job teaching this concept and showing examples. In Jest, the key is jest.fn() or jest.spyOn() for mocking methods. For our purposes, mocking allows us to fashion a fake function or object without calling the true implementation, avoiding unwanted side-effects. For example, if I have a class controlling an alert noise in my application, I can call jest.spyOn(NoiseService, 'playLoudHorn') to have that function call, when tested, not try to make a real noise. If the method is supposed to return a boolean to indicate success/failure, you can do .mockReturnValue(true) on the end of a mock to have the mocked function return true for this test. The hard part about stubbing/mocking is getting access to the dependency so we can spyOn it or so we can replace it entirely with a mock. The rest of this article is about several ways to inject our mocks into a React hook. In pure functions, all dependencies are passed as arguments to the function. The benefit of this approach is it makes providing (injecting) dependencies during tests straight-forward. Outside of testing, if the dependencies are given default values, the original functionality can be preserved. In this useTime() hook ( read the Medium article for implementation details ), a _getTime parameter is exposed to allow specifying a different function to get the current time. ( I used Luxon for handling DateTimes , I like it more than momentjs) Suppose I want to control what time my useTime() hook thinks it currently is. Instead of mocking the Date object or spying on DateTime.local , I can simply pass in a mock function as _getTime . Here's a test where we do exactly that: (For this test, the actual return value of _getTime is not critical, so I used a string) Of course, by specifying a default function, I can avoid specifying the getTime option when consuming the hook in my components. Here's a sample usage of the useTime hook, without any _getTime specified. An alternative way to control/spy/mock an import is to use the Jest module mocking tools (or tools like proxyquire ) to inject mocks through the module system. Just specify the exact string used for require-ing the dependency, then provide your own mock before importing the unit under test. While this example works, I find with larger test files it can be prone to mutation by tests and can, as a result of mutation behavior, become more complicated. Tests should be easy. Dependencies in React can be provided through the React Context API. This is how components connected to Redux store are able to access state, for example. Let's look at a trivial hook which accesses a context to build a URL string based on a configuration object. We're going to test useResumeURL() . Here's a sample usage: In our test, we can rely on default context, or we can specify a new context using the wrapper option from @testing-library/react-hooks to loop in the context's Provider to inject a mock context value. Let's do both: Made a quick testing factory to build wrappers, so future tests would not be tied to a specific set of values. Keeps tests independent, which is a best practice. Some dependencies can be controlled in unconventional ways. setTimeout and setInterval (generally, the concept of time) can be controlled using Jest ( and Sinon.js, used in this example ). Through experimentation, I found the passage of time has to occur inside act callbacks for the hook to register the effects properly. Another common unconventional dependency mock wraps the XMLHttpRequest (XHR) object so you can block and assert on outgoing network requests, plus control the responses and test the resulting behavior (very nice for testing uncommon API failure scenarios).

Thumbnail Image of Tutorial Testing Custom React Hooks with Jest