Tutorials on Reactdom

Learn about Reactdom 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

NPM: What are project dependencies?

Code dependencies are like Lego's . We're able to pull in other people's code; combining and stacking different packages together to fulfill our goals. Using dependencies greatly reduces the complexity of developing software. We can take advantage of the hard work someone has already done to solve a problem so we can continue to build the projects we want. A development pipeline can have multiple kinds of code dependencies: In JavaScript, we have a package.json file that holds metadata about our project. package.json can store things like our project name, the version of our project, and any dependencies our project has. Dependencies, devDependencies, and peerDependencies are properties that can be included in a package.json file. Depending on the instance where code will be used changes the type of dependency a package is. There are packages that our users will need to run our code. A user is someone not directly working in our code-base. This could mean a person interacting with an application we wrote, or a developer writing a completely separate library. In other words, this is a production environment. Alternatively, there are packages that a developer or system only needs while working in our code. For example linters, testing frameworks, build tools, etc. Packages that a user won't need, but a developer or build system will need. Dependencies are packages our project uses in production . These get included with our code and are vital for making our application run. Whenever we install a dependency the package and any of its dependencies get downloaded onto our local hard drive. The more dependencies we add, the bigger our production code becomes. This is because each new dependency gets included in the production build of our code. Evaluate adding new dependencies unless they're needed! Dependencies are installed using npm install X or yarn add X Packages needed in development , or while developing our code, are considered dev dependencies. These are programs, libraries, and tools that assist in our development workflow. Dev dependencies also get downloaded to your local hard drive when installed, but the user will never see these dependencies. So adding a lot of dev dependencies only affects the initial yarn or npm install completion time. Dev Dependencies are installed using npm install --save-dev X or yarn add --dev X Peer dependencies are similar to dependencies except for a few key features. First, when installing a peer dependency it doesn't get added to your node_modules/ directory on your local hard drive. Why is that? Well, peer dependencies are dependencies that are needed in production , but we expect the user of our code to provide the package. The package doesn't get included in our code. This is to reduce including multiples of the same dependency in production . If every React library included a version of React as a dependency, then in production our users would download React multiple times. Peer dependencies are a tool for library owners to optimize their project size. Peer Dependencies are installed using yarn add --peer X I recently released a course, Creating React Libraries from Scratch, where we walk through content just like how NPM dependencies work, and a lot more! We start with an empty project and end the course with a fully managed library on npm. To learn more click the link below! Click to view Creating React Libraries from Scratch!

Thumbnail Image of Tutorial NPM: What are project dependencies?

How to Write Your First Component Test in React + TypeScript App

In the previous post , we created a unit test for a function. In this post, we're going to create a unit test for a component using @testing-library/react . Since we're using Create React App the React Testing Library is already installed in our dependencies. If you don't have it, install the package using: We will create a Greetings component with the greetings text inside and a button for sending friendly waves 😊 Let's create and review a component first: This component takes a name and an onSendWaves function as props. The name will be rendered in the greetings text, and the callback function will be called whenever the button is pressed. The button can be hidden if the callback function is not provided. We need to test 3 things here: Let's start with the first one. For the first test, let's check if the greetings text is rendered correctly. Let's break the test code down a bit. In describe and it we explain the assumption we want to test as we did in the previous post . Then, we use the render method from the @testing-library/react package. This method renders the component provided in arguments and appends it to the body of the document. Once we're rendered the component we can use the screen object to get access to the render result. It provides a set of queries for us to find the required element. If you saw tests with RTL before, you might have seen this: We use getByText query to find an element that contains the given text. Notice that React Testing Library doesn't focus on the component implementation. We don't explicitly define where to look for that text, instead, we tell what to find and RTL will try to find it for us. Finally, we check that the required element is indeed in the document. We can select elements not only by the text they contain. In fact, there are quite a few ways to query elements . Let's review a couple of types of queries : Another cool (and a bit confusing at first) feature is the query type. Until now we only saw a getBy query. It searches for a single element and returns it if found and throws an error if didn't find. There are also other types of queries for different types of searches : The queryBy and queryAllBy are usually used to make sure that elements are not in the document. The findBy and findAllBy are used to search for elements that are not available at first render. It is hard to pick a query at first, that's why there is a priority guideline in the docs and the cheatsheet to help us. Now, let's test that when the onSendWaves is provided the button gets rendered: Here, we use getByRole query because we need to find a single button element. React Testing Library has the fireEvent object that can help with simulating browser events, however, it is more convenient to use the user-event library since it provides more advanced simulation of browser interactions. Let's install it with: Now let's test that when the button is pressed it fires the callback: First of all, we use jest.fn method to create a mock function . This mock will help us to test how many times and with what arguments this function has been called. On the last line, we check that the mock instance ( onSendWavesMock ) is called at least once with a given text. Another text will result in the failing test. To click the button we use the userEvent object from React Testing Library. It provides most common actions like click, input changes, and so on. In our case, we need to test the click action, so we use the click method and pass the element that should be pressed. In the next post, we will test react hooks with @testing-library/react-hook .

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 Write Your First Unit Test in React + TypeScript App

Tests make sure that changes in code don't break its functionality. For testing an app, we need a test runner. Create React App provides us a test runner called jest . Let's create a new app and inspect what it contains. The src directory contains all the app code and a file called App.test.tsx . This file contains a test that makes sure that the App component renders a link: Let's break it down and write our own tests to understand what's going on. Every test is a statement that claims something. In our case, test in App.test.tsx claims that the App component should render a “Learn React” link. This kind of statements consist of 3 stages: This is true for the test in the App.test.tsx , let's check: This is considered a good practice to structure tests in this way. Tests that comply the Arrange-Act-Assert structure are clean and easy to read. Let's start with a test for good ol' functions, and then come back to testing components. Testing functions is a bit easier to grasp and it will be much easier to apply this knowledge later, when testing components. Open App.tsx and add a new function: Now, open the App.test.tsx file and start testing this divide function. First of all, we need to describe what we want to test. For descriptions, jest has a describe function , which we can use like this: We can indent describe functions to create describe specific details about current tests we write: For actually running tests jest has it and test functions . We can use either of those, they do the same. The only difference is the name semantics: we can use it to construct test sentences more naturally. For example: Finally, let's actually write our first test! In the Assert stage we used a function called expect . It is also a jest global function . It returns an object with a bunch of useful methods to use. The full list of them we can find in the docs . In our case we use .toEqual method to check if the expect argument is equal to toEqual argument, i.e. if the expected result is equal to actual result. Now, it is time to check if our test is working, open the console and run: You will see that all the tests are passing: This is great! But we have to break our test 🤯 The immediately appearing thought is: “What would we do that?”. The reason is that we need to make sure that our test is working and that it tests the right thing . Let's look at the example: So, to test our test we're going to break it and see if it breaks with the correct intent. In this case we will see an error output: If we examine the reason why the test has failed, we will see that expected value is not equal to actual. This reason is valid, so the works correctly. Now let's try to test that divide function doesn't allow to divide by 0. We know that if we try to do that it will throw. To check functions that may throw we will use .toThrow method . Notice that we pass a () => divide(1, 0) here, this way jest knows that the occurred error is expected and there is no need to stop the testing itself. Again, let's test our test: The output will be: Thus, we know that our tests are correct. Later, we will use jest for writing tests for React component.

Thumbnail Image of Tutorial How to Write Your First Unit Test in React + TypeScript App

A Closer Look at ReactDOM.render - The Need to Know and More

📰 In this post, we will learn about render(), a core function of ReactDOM. Along with this, we will also take a closer look at the reconciliation process, how ReactDOM works under the hood, and it's use-cases.The ReactDOM library is not often talked about when working with React, however, It is vital for any React developer to know how ReactDOM.render is used to inject our React code into the DOM. It is also good to get a brief idea of how it works under the hood, so we can write better code to accommodate the architecture. According to the React docs , This blog post presents an overview of the ReactDOM library. Since it involves some core ReactJS concepts, it is better to be familiar with the library and how it works. Even if you don't have a deep understanding of React, this blog post can help demystify a lot of concepts related to rendering on the DOM. Before moving to ReactDOM, let's take a brief look at the Document Object Model. The Document Object Model (DOM) is a code representation of all the webpages that you see on the internet. Every element , such as a button or image that you see on the web-page is a part of a hierarchy of various elements within a tree structure. This means each element (except the root element) is a child of another element. This structure enables you to easily interface your JavaScript code with HTML to create highly powerful and dynamic web applications. The way that web developers usually work with the DOM to develop interactive websites, is by finding a DOM node and making the required changes to it, such as changing an attribute or adding a child node. However, for highly dynamic web applications where the DOM needs to be updated frequently, applying these required changes can be a slow process, as the browser ultimately has to update the entire DOM every time. To combat this problem, React works with a Virtual DOM , which is just a representation of the actual DOM that is used behind the scenes to optimize the update process. When a React element is updated, ReactDOM firstly updates the Virtual DOM. After that, the difference between the actual DOM and the Virtual DOM is calculated, and only the unique part . This means that the whole DOM does not need to be updated every single time. This process, also known as “reconciliation” , is one of the things that helps us to build blazing fast Single Pages Applications (SPAs) with React. ReactDOM is a package that provides methods that can be used to interact with the DOM, which is needed to insert or update React elements. It provides many helper functions such as: And more... Most of the time when building Single Page Applications (such as with create-react-app ), we usually create a single DOM container and call the render method once to initialize our React application. Since this method is always used when working with React, learning about the working of ReactDOM.render can greatly benefit us as React developers. The render method can be called the primary gateway between React and the DOM. Let’s say you have defined a React element ( <Calculator /> ), as well as a DOM node to act as a container for that element (div with the ID of “container”). Now, you can use ReactDOM.render to render the element within that container using the syntax given below: ReactDOM.render(< Calculator />, document.querySelector("#container")) The statement above returns a reference to the component that you have created. If it is a functional component, it returns null. Parameters: React elements are defined in a tree structure . This means each element is essentially a child of another React element. However, for the root element, we need to create an element (DOM Node) in our HTML code to act as a container for our React element tree, which can be accessed via ReactDOM.rende r. For a better understanding, the figure below defines an example React component tree: In the above diagram, we can see that <Calculator /> is our root React element , which is rendered into the container div within the HTML code. Breaking it down further, the <Calculator /> element has two children, <Display /> and <KeyPad / >. Similarly, <KeyPad /> is broken down into <NumKeys /> , <FunctionalKeys /> and <Operators /> . This is what those components will look like in code: As defined above, the reconciliation process is when the React virtual DOM (AKA the tree of React elements) is checked against the actual DOM, and only the necessary updates are reflected. In the previous versions of React, a linear synchronous approach was used to update the DOM. It became obvious very quickly that this can greatly slow down our UI updates, negating the whole reason why reconciliation exists in the first place. In React 16, the team re-wrote major parts of the reconciliation algorithm to make it possible to update the DOM asynchronously. This is possible because of the Fiber architecture which lies at the core of the new implementation. Fiber works in two phases, This phase is triggered when a component is updated through state or props. Therefore, the standard React protocol is followed, where a component is updated and lifecycle hooks are called, after which the DOM nodes that need to be updated are calculated. In Fiber, these activities are termed as “work” . Before React 16, having multiple work tasks could make our user interface look and feel sluggish because a recursive approach was used with the call stack. The problem with recursion is, that the process only stops when the call stack is empty, which can result in higher time complexity. As more work is performed, more computational resources are utilized. The updated architecture utilizes the Linked List Data Structure within its algorithm to handle updates. This, used in conjunction with the requestIdleCallback() function provided by newer browsers makes it possible to perform asynchronous tasks (or work) more efficiently. Each “work” unit is represented by a Fiber Node . The algorithm starts from the top of the Fiber Node Tree and skips nodes until it reaches the one which was updated. Then it performs the required work and moves up the tree until all the required work is performed. During the commit phase, the algorithm first calls the required lifecycle methods before updating or unmounting a component. Then, it performs the actual work, that is, inserting, updating or deleting a node in the DOM. Finally, it calls the post-mutation lifecycle methods componentDidMount and componentDidUpdate . Along with this, React also activates the Fiber Node Tree that was generated in the previous phase. Doing this ensures synchronization between the tree of React elements and the DOM, as React knows what the current status of the Virtual DOM is. Whew... however abstract, we now have a faint idea of how the reconciliation process works behind the scenes. Let’s move back to the practical side of things, and discuss how we can use ReactDOM.render in different scenarios. Assuming we are working with a Single Page Application, we will only need to instantiate the root element (usually App.jsx ) at a single location in the DOM. Therefore, oftentimes the lone index.html file is not even touched at all. All we need to do is create a container, and render our React root element to it, as described above in the Calculator example. We can also use ReactDOM.render to integrate React in a different application. This is why we call React a library, not a framework . You can use it as little as possible or as much as possible, as it completely depends on your use-case. We can create a wrapper function for our React module. All the required props can be passed to the function, and sent down to the component which is rendered through ReactDOM.render, just like it would be for a single page application. It is important to export the function, as we will need to call it within our JavaScript code. In the index.html file shown above, we are importing the script that renders our root React component, and then we call the function using plain JavaScript. We can also pass parameters, such as props for our React component, through this function. It is better to initialize React components after the document has loaded. You can also use ReactDOM.render multiple times throughout the application. This means that if you are creating a new website, or modifying an existing website that does not use React yet, you can use ReactDOM.render to generate some pages using React, while others do not use the library. When you unmount a React component from the DOM, it is important to call unmountComponentAtNode() according to the syntax given below to ensure there are no memory leaks. ReactDOM.unmountComponentAtNode( DOMContainer ) This is why the React team suggests using a wrapper for your React root elements. Doing this ensures that you can mount and unmount React nodes according to the design of your website. For example, moving from one React page to another that uses separate React root elements, it is possible to integrate the wrapper API with the page transition, which can automatically unmount the component for you. Similarly, you can also write the logic in your wrapper to unmount a React root component within the same page, as soon as its work is done. To update a component, you may call ReactDOM.render again for the same React element and DOM node. However, one thing that is important to note is that ReactDOM.render completely replaces all of your props each time this function is called. This means, you must also pass all of the other required props to the element that you are rendering, which can be an issue. The reason for the props being replaced is because React elements are immutable. The React team explains how you can create a wrapper to set the previous props again . Although render() is the most commonly used ReactDOM method, there are a few more available at your disposal. Let’s take a look at two of those. It is similar to render() , however, it is used when rendering pages through Server Side Rendering (SSR) . It integrates the necessary event handlers and functions to the markup that has been generated. Portals can be created to render a component outside of the React component tree of that specific component. This can be highly useful to generate elements somewhere unrelated on the page. To sum it up, ReactDOM acts as a powerful interface between our React component tree and the DOM. The most commonly used method from ReactDOM is render() , which can be used to connect entire React applications to the DOM. Once the React element and it’s child tree have been inserted into the DOM, the reconciliation process handles everything related to updates. Due to this process, whenever we update a part of our component tree, only the changes in that part are reflected in the actual DOM, thereby saving us a lot of extra computation. React and ReactDOM provides powerful functions such as render() that make it easy to create fast and snappy Single Page Applications through React, which makes React such a popular front-end development library.

Thumbnail Image of Tutorial A Closer Look at ReactDOM.render - The Need to Know and More