Learning React in 2024 – Everything You Need to Know Before you Start

This is my attempt to unwind the topic of Learning React in 2024 and provide a better way to get up to speed quickly on React along with helpful links to React related articles and videos. I sincerely hope this blog article helps you and me both learn React a little faster!

I need to learn React so this the best way I know how to learn a subject deeply is to write a blog article about it.

I’ve already completed two online tutorials but the topic of React still seems a bit daunting jumping in now, in 2024. There’s a bit of history and baggage to the story of React that would be helpful for you to know as someone just starting out.

I sincerely hope this blog article helps you and me both learn React a little faster!

What is React and What Problem Does it Solve?

React, a popular JavaScript library for building user interfaces, was created to address several challenges in web development. Here are the key problems that React aims to solve:

  1. Efficient DOM Manipulation: One of the most significant challenges in dynamic web applications is efficiently updating the Document Object Model (DOM) in response to user interactions or data changes. The DOM is inherently slow when it comes to frequent updates, especially in large applications. React introduces the concept of a virtual DOM, a lightweight copy of the actual DOM. React only updates parts of the actual DOM that have changed, rather than re-rendering the entire DOM, which significantly improves performance.
  2. Reusable Components: React is based on a component-based architecture. This approach allows developers to build encapsulated components that manage their own state, then compose them to make complex UIs. These components can be reused, which enhances code maintainability, makes the codebase more manageable, and accelerates the development process.
  3. Unidirectional Data Flow: React enforces a unidirectional data flow, which means that the state flows in one direction, making the logic of your application more predictable and easier to understand. This is particularly beneficial for larger applications, as it helps in debugging and maintaining the codebase.
  4. Declarative UI: React allows developers to describe their UIs declaratively. Instead of telling the browser how to update the UI, developers simply describe the UI as a function of the state. When the state changes, React takes care of updating the UI to match the new state. This makes the code more readable and easier to debug.
  5. Integration Friendly: React can be easily integrated into existing projects. It doesn’t require adopting an entirely new ecosystem, making it a popular choice for gradually modernizing large, established codebases.
  6. Rich Ecosystem and Community Support: React has a vast ecosystem of libraries and tools, making it easier to add features such as routing, state management, form handling, etc. The large community around React means extensive resources, tutorials, and third-party packages are available, which can accelerate development.
  7. SEO Friendly: Unlike some JavaScript frameworks, applications built with React can be rendered on the server (using Node.js), which means that search engines can index the content of web applications, improving their SEO.

By addressing these issues, React has become a cornerstone in the development of modern web applications, offering both performance and productivity benefits.

A Brief History of React

We’ll cover the versions and features of React later in this article but for now we need a a brief history of React to get us going:

  1. Initial Development and Release: React was first developed at Facebook. The project was spearheaded by Jordan Walke, a software engineer at Facebook. It was influenced by XHP, an HTML component framework for PHP. React was initially used in Facebook’s newsfeed in 2011 and later in Instagram.com.
  2. Open Source Release: React was officially open-sourced at JSConf US in May 2013. The open-source release included React’s signature feature of virtual DOM, which allowed for efficient updating and rendering of UI components.
  3. Growing Popularity: After its open-source release, React gained popularity rapidly. Developers appreciated its component-based architecture which made the creation of complex user interfaces more manageable and scalable.
  4. Introduction of React Native: In 2015, Facebook announced React Native, an extension of React that allows building native mobile apps for iOS and Android using React’s framework. This further boosted React’s popularity as it enabled developers to use a single codebase for web and mobile applications.
  5. Addition of Hooks: In 2018, React introduced a new feature called Hooks. Hooks allowed functional components to have access to state and other React features, which were previously only possible with class components. This was a significant update as it allowed for cleaner and more concise code.
  6. Ongoing Developments: React has continued to evolve with regular updates to improve performance, developer experience, and introduce new features. The React team focuses on backward compatibility, ensuring that updates do not break existing applications.

React’s design and architecture have influenced many other libraries and frameworks in the web development community. Its component-based architecture is now a standard approach in many modern web development frameworks. React’s popularity continues to grow, and it remains one of the leading tools for building web and mobile applications.

What is State Management in React?

State management in React applications is a crucial aspect, as it involves handling the data or state of the application that might change over time. Understanding how state is managed in React is key to building dynamic and interactive user interfaces. Here’s an overview:

Basic State Management in React

  1. Component State (useState Hook):
    • In React, each component can have its own internal state, managed using the useState hook in functional components.
    • This state is encapsulated within the component and can be updated using a setter function provided by useState.
    • It’s suitable for simple and local states like a button’s click status, form inputs, etc.
  2. useReducer Hook:
    • For more complex state logic, the useReducer hook is used. It lets you manage the local state of the component with a reducer function.
    • This approach is similar to how state is managed in Redux, making it easier to handle complex state logic in a predictable way.

Global State Management

For managing state that needs to be shared across multiple components:

  1. Context API:
    • The Context API allows you to share state across the entire app or across specific parts of it without having to pass props down through multiple levels of components (prop drilling).
    • It’s useful for themes, user settings, authentication status, etc.
  2. External Libraries:
    • Redux: A popular choice for managing global state in larger applications. It centralizes the application’s state and updates it in a predictable way.
    • MobX: Uses observables and reactions for state management, allowing for more dynamic state changes.
    • Recoil, Zustand, etc., offer different approaches and features for global state management.

State Management Patterns

  1. Lifting State Up:
    • Often, several components need to reflect the same changing data. React solves this by lifting the shared state up to their closest common ancestor.
  2. Prop Drilling:
    • This involves passing state down from a parent component to a child component through props. This can become cumbersome in deeply nested component trees, hence the use of Context or global state management libraries.
  3. Controlled vs. Uncontrolled Components:
    • In controlled components, form data is handled by the React component state.
    • Uncontrolled components manage their own state internally, and you query the DOM using a ref to find its current value when you need it.

Performance Considerations

  1. Minimizing Re-renders:
    • Efficient state management is crucial for performance. Unnecessary state changes can lead to excessive re-rendering of components.
    • Using techniques like memoization with React.memo, useMemo, and useCallback can help prevent unnecessary renders.
  2. State Immutability:
    • Always treat state as immutable. This means you should not modify the state directly, but rather return a new object or value when updating the state.
  3. Selective State Updates:
    • Update only the parts of the state that need to change. This is where tools like Redux or useReducer become valuable, as they enforce patterns that help manage updates efficiently.

In summary, state management in React is about handling and updating the data that a component or an application needs to function and render. The choice of state management strategy depends on the complexity of the application and the scope of the state (local vs. global). Each method has its use cases and trade-offs, and often, a combination of these methods is used in a single React application.

Options for State Managemet in React

Managing state is a crucial aspect of building applications with ReactJS. There are several options for state management in React, each with its own advantages and use cases. Here’s a list of some popular state management options:

  1. React’s Built-in State Management:
    • useState: A Hook that lets you add React state to functional components.
    • useReducer: A Hook that is preferable for managing more complex state logic in functional components.
  2. Context API:
    • Built into React, the Context API allows you to share state across the entire app or parts of it easily, without having to pass props down through multiple levels of components.
  3. Redux:
    • A popular third-party library for managing application state. It’s often used for larger, more complex applications due to its robust ecosystem and strong principles of predictable state updates.
  4. MobX:
    • A state management library that utilizes observable states and reactions. It’s known for being more flexible and less boilerplate-heavy than Redux, with a focus on simplicity and scalability.
  5. Recoil:
    • Developed by Facebook, Recoil addresses some of the limitations of Context API by providing a more granular approach to state management in React. It’s designed to work with larger applications and provides more optimized performance for global state.
  6. Zustand:
    • A small, fast, and scalable bearbones state-management solution using simplified flux principles. It has a simple and readable API and doesn’t require reducers.
  7. Apollo Client (for GraphQL):
    • If you are using GraphQL, Apollo Client provides powerful state management features integrated with data fetching.
  8. React Query:
    • Not exactly a state management library in the traditional sense, but it’s useful for managing server state – caching, synchronizing, and updating server data.
  9. XState:
    • A library for state machines and statecharts, which can be an excellent tool for managing complex application states and workflows.

Each of these options has its strengths and best use cases. The choice depends on the specific requirements of your project, such as the size of your application, the complexity of your state logic, and your team’s familiarity with the library.

When Do I Need to Use a State Management Library?

Using a state management library in a React application is a decision that depends on the complexity and scale of the application. While React’s built-in state management capabilities (using useState, useReducer, and the Context API) are sufficient for many applications, there are certain scenarios where introducing a state management library like Redux, MobX, or Recoil can be beneficial:

  1. Complex State Logic: When your application has complex state logic that involves multiple components, a state management library can provide a more structured and maintainable approach.
  2. Large Application with Many Components: In a large-scale application with a significant number of components, managing the state only with React’s built-in features can lead to challenges like prop drilling (passing props through many layers of components) and state synchronization issues across components.
  3. Global State Management: If your application requires a lot of global states that need to be accessed or modified by many components at different nesting levels, a state management library can offer a more efficient and easier way to handle this.
  4. Performance Optimization: State management libraries often come with performance optimization strategies out of the box, such as selective rendering and efficient state updates, which are crucial for large applications.
  5. Predictable State Updates with Redux: Redux, in particular, enforces a predictable state update mechanism (through actions and reducers), which can be beneficial for debugging and understanding the flow of state in the application.
  6. Middleware and Side-Effects Management: If your application needs to handle side effects (like accessing a database, making API calls, etc.) in response to state changes, libraries like Redux with middleware (e.g., redux-thunk, redux-saga) can be very helpful.
  7. Shared State Across Multiple Routes: In single-page applications (SPAs) where you need to maintain state across routes, using a state management library can help keep the state consistent and easily accessible.
  8. Developer Tools and Ecosystem: State management libraries often come with powerful developer tools (like Redux DevTools) and a rich ecosystem of middleware, which can significantly enhance the development experience.
  9. Time Travel and Debugging: Some state management libraries offer advanced features like time travel debugging, which can be invaluable in a development environment to track state changes over time.
  10. Community and Resources: The larger community and extensive resources available for popular state management libraries can be a deciding factor, especially in terms of finding solutions to common problems and hiring developers who are familiar with these tools.

In summary, the decision to use a state management library in a React application should be based on the specific needs of your project. For simple to moderately complex applications, React’s context and hooks might be sufficient. However, for larger, more complex applications, especially those needing fine-grained control over global state and side-effects, a state management library can be a valuable addition.

To address these security concerns, React developers should follow best practices like validating and sanitizing user input, using secure HTTP headers, keeping dependencies updated, and implementing proper authentication and authorization mechanisms. Additionally, regular security audits and code reviews are essential in maintaining the security of a React application.

React Versions and Features

As of April 2023, React has seen several major versions, each introducing new features, improvements, and sometimes significant changes in how developers build React applications. Here’s an overview of the major versions of React and their key differences:

React 16 (September 2017)

  1. Fragments: This feature allows components to return multiple elements without requiring an extra wrapper.
  2. Error Boundaries: Error boundaries provide a way to catch JavaScript errors in their child component tree, log them, and display a fallback UI.
  3. Portals: Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
  4. Fiber Reconciliation Engine: This was a complete rewrite of the core algorithm, improving the perceived responsiveness of complex applications through incremental rendering.

React 16.x Series

  • Subsequent minor releases in the React 16 series introduced more features:
    • Context API Overhaul: A more efficient and flexible Context API.
    • Lazy Loading with React.lazy and Suspense: Allows components to be lazily loaded, which can improve performance.
    • Hooks (16.8): Introduction of Hooks, a feature that lets you use state and other React features without writing a class.

React 17 (October 2020)

  1. No New Features for Developers: React 17 was more about making it easier to upgrade React itself. It didn’t add new features for developers but instead laid the groundwork for future long-term improvements.
  2. Changes to Event Delegation: React 17 changed how event delegation works, attaching event handlers at the root DOM container rather than at the document level.
  3. Gradual Upgrades: React 17 made it easier to embed a tree managed by one version of React inside a tree managed by a different version of React.

React 18 (March 2022)

  1. Concurrent Rendering: This version introduced concurrent features that enable React to prepare multiple versions of the UI at the same time.
  2. Automatic Batching: React 18 batches more rendering updates by default, reducing the number of re-renders needed.
  3. New Root API: The new root API enables the use of concurrent features and provides a more straightforward way to boot up a React application.
  4. Suspense for Server Rendering: React 18 includes support for suspense on the server, allowing developers to wait for data to load before sending HTML to the client.

Future Versions (Beyond React 18)

  • Future versions of React are expected to continue building on concurrent features, providing more powerful ways to optimize application performance.
  • The React team might also introduce new APIs and deprecate older patterns as the library evolves.

Each version of React builds upon the previous one, often with a focus on performance, developer experience, and simplifying the creation of complex UIs. It’s important for developers to keep up with these changes for optimal application performance and to take advantage of the latest features and improvements. React’s development has been characterized by a strong commitment to backward compatibility, making upgrades typically straightforward for developers.

What Backend Frameworks Are Commonly Used with React?

React, being a frontend library, can be paired with a variety of backend frameworks depending on the needs of the application. Some of the most common backend frameworks used with React are:

  1. Node.js with Express.js:
    • Node.js is a JavaScript runtime that allows you to write server-side code in JavaScript. Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. This combination is popular due to its full JavaScript stack development capability, which can streamline the development process.
  2. Ruby on Rails:
    • Ruby on Rails (Rails) is a server-side web application framework written in Ruby. It’s known for its convention over configuration philosophy, which makes it fast for building applications. Rails works well with React, especially when using Webpacker, a module bundler for modern JavaScript applications.
  3. Django:
    • Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It’s known for its “batteries-included” philosophy and is particularly well suited for building complex, data-driven websites. Django’s REST framework is often used to build APIs that React can interact with.
  4. Spring Boot:
    • Spring Boot is an extension of the Spring framework that simplifies the initial setup and development of new Spring applications. It’s popular in the Java community and is known for its ability to create stand-alone, production-grade Spring based applications easily.
  5. ASP.NET Core:
    • ASP.NET Core is a cross-platform, high-performance, open-source framework for building modern, cloud-based, Internet-connected applications. It’s developed by Microsoft and is a great choice for building secure, scalable backends in C#.
  6. Flask:
    • Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries. It’s a good choice for smaller applications or when you need more control over the components you use.
  7. Laravel:
    • Laravel is a PHP web application framework with expressive, elegant syntax. It’s a strong choice for developers who are comfortable with PHP and need a framework that can handle complex backend requirements with ease.
  8. Go (often using frameworks like Gin or Beego):
    • Go, also known as Golang, is a statically typed, compiled programming language designed at Google. It’s known for its simplicity and performance. Frameworks like Gin or Beego make it easier to build performant RESTful APIs that React can interact with.
  9. GraphQL Servers (Apollo Server, etc.):
    • GraphQL is a query language for APIs. Instead of multiple REST endpoints, GraphQL uses a single endpoint and gives clients the ability to query exactly the data they need. Apollo Server is a community-driven, open-source GraphQL server that works well with any GraphQL schema.
  10. Firebase / Firestore:
  • Firebase, particularly Firestore, which is Firebase’s new database, is a popular choice for simpler applications or applications that require real-time data updates. It’s a NoSQL cloud database that syncs and stores data in real-time.

These backend frameworks and technologies offer various features and suit different types of projects. The choice often depends on the application requirements, team expertise, and other factors like scalability, performance, and ease of development.

Are there Alertnatives to Using React?

There are several alternatives to React for building user interfaces, particularly in web development. Each alternative comes with its own set of features, philosophies, and use cases. Here are some of the notable ones:

  1. Vue.js:
    • Vue is a progressive JavaScript framework used for building UIs and single-page applications (SPAs). It’s known for its simplicity, flexible design, and a gentle learning curve. Vue’s ecosystem includes tools like Vue Router for routing and Vuex for state management.
  2. Angular:
    • Developed and maintained by Google, Angular is a comprehensive framework for building dynamic web applications. It’s a full-fledged MVC (Model-View-Controller) framework and includes features like two-way data binding, dependency injection, and a robust set of tools and components. Angular is often chosen for enterprise-level applications.
  3. Svelte:
    • Svelte is a relatively new framework that shifts much of the work to compile time, producing highly optimized vanilla JavaScript at the end. Unlike React or Vue, there’s no virtual DOM. Svelte is known for its simplicity and performance benefits.
  4. Ember.js:
    • Ember is an opinionated framework for building ambitious web applications. It provides a strong convention-over-configuration philosophy and comes with its own templating engine and router. It’s often appreciated for its thorough documentation and built-in best practices.
  5. Backbone.js:
    • One of the earliest frameworks in modern web development, Backbone.js provides the minimal structure needed to build web applications by providing models with key-value binding and custom events. It’s known for being lightweight but requires more manual management of the UI and state.
  6. Preact:
    • Preact is a lightweight alternative to React with a similar API. It’s much smaller in size compared to React but lacks some features like PropTypes and children as a function. It’s a good choice for performance-critical applications that need a minimalistic approach.
  7. LitElement and Lit HTML:
    • Developed by Google, LitElement (part of the Lit library) is a simple base class for creating fast, lightweight web components. It’s used for creating custom elements with a reactive rendering system.
  8. Blazor (WebAssembly):
    • For developers coming from a .NET background, Blazor allows building interactive web UIs using C# instead of JavaScript. Blazor WebAssembly runs client-side C# code directly in the browser, using WebAssembly.
  9. Elm:
    • Elm is a functional language that compiles to JavaScript. It’s known for its strong type system, no runtime exceptions, and an architecture that enforces unidirectional data flow. It’s a good choice for developers interested in functional programming.
  10. Vanilla JavaScript/HTML/CSS:
  • For simpler applications, or for developers who prefer not to use a framework or library, building with plain JavaScript, HTML, and CSS is always an option.

Each of these frameworks and libraries has its strengths and is suitable for different kinds of projects and developer preferences. The choice depends on the specific requirements of the project, such as the size and complexity of the app, the development team’s expertise, and other factors like performance and scalability needs.

Top Security Concerns When Using React

When using React, a JavaScript library for building user interfaces, there are several security concerns that developers need to be aware of. These concerns are not necessarily specific to React itself, but are part of web development in general. React provides tools and follows patterns that help mitigate many common security risks, but it’s still crucial for developers to be vigilant and follow best practices. Here are the top security concerns when using React:

  1. Cross-Site Scripting (XSS) Attacks: XSS is a common security vulnerability in web applications. React inherently protects against XSS by escaping strings used in JSX before rendering them. However, developers can inadvertently introduce XSS risks if they use dangerouslySetInnerHTML improperly or interpolate user input in URLs or JavaScript code.
  2. Cross-Site Request Forgery (CSRF) Attacks: CSRF attacks involve tricking a user into submitting a request to a web application where they are authenticated. While React does not provide built-in tools to prevent CSRF, developers need to implement CSRF tokens and handle them on the server side.
  3. SQL Injection: While React is a frontend library and does not directly interact with databases, SQL injection risks can arise if user input from a React application is not properly handled in the server-side code.
  4. Third-Party Libraries: Using third-party libraries can introduce security vulnerabilities if the libraries are not actively maintained or if they contain insecure code. It’s essential to keep dependencies up to date and audit them regularly for security issues.
  5. Server-Side Rendering (SSR) Vulnerabilities: When using frameworks like Next.js for server-side rendering with React, developers should be aware of potential security issues like user input not being sanitized properly, which could lead to XSS attacks.
  6. Exposing Sensitive Data: Accidentally exposing sensitive data through client-side code, such as API keys or secrets, is a risk. Such information should be kept on the server and not included in the frontend code.
  7. Insecure Data Transmission: Not using HTTPS for data transmission can expose data to interception. It’s important to ensure that all data transmitted by the React application is done over secure channels.
  8. Security Misconfigurations: Common misconfigurations, such as not setting HTTP headers properly to protect against clickjacking, content sniffing, etc., can lead to security vulnerabilities.
  9. Improper Authentication and Authorization Checks: In single-page applications (SPAs) built with React, it’s essential to ensure that authentication and authorization checks are correctly implemented, preferably on the server side.
  10. Component-Level Security: When building reusable components, it’s crucial to ensure that these components do not introduce security vulnerabilities, especially when dealing with user input or displaying data fetched from external sources.

Helpful React Related Articles

Why don’t you need Redux anymore?
by Gokul Manoharan
https://www.linkedin.com/pulse/why-dont-you-need-redux-anymore-gokul-manoharan-mrt6f/

Videos I’ve Found Helpful in Learning React

React in 100 Seconds

Summary

React in 100 Seconds

React Redux for Beginners

I sincerely hope my blog article and the references I’ve linked to help you learn React as little faster as it is a large and ever changing topic.

I’ll come back and update this article as I’m learning React and gain new insights as I gain experience.

JavaScript Error: Uncaught TypeError: Cannot read property ‘addEventListener’ – Solved!

JavaScript Event Listener Error: Cannot Read Property ‘addEventListener’

I’m working on building some JavaScript event listeners for a project.

While working on a demo based on this YouTube Video. I got an error that took me a couple of minutes to figure out.

I encountered this error, JavaScript Event Listener Error: Cannot Read Property ‘addEventListener’, while working through this video on creating JavaScript Event Listeners.

If you follow this video and have issues getting your JavaScript Event Listener to work then read on to my solution below to see how I fix my below.

JavaScript Event Listener Example Video

The JavaScript Code to Add an EventListener

const grandparent = document.querySelector(".grandparent")

const parent = document.querySelector(".parent")

const child = document.querySelector(".child")

 grandparent.addEventListener('click', e => {

    console.log(e)
     }) 
 

JavaScript Uncaught TypeError: Cannot read property ‘addEventListener’ of

Solution: Move JavaScript to End of File

The root cause of the error is that if we load the JavaScript file before the DOM element loads then the const reference to grandparent class fails as it has not yet been loaded in to the DOM as the web page is rendering.

By simply moving the JavaScript tag to the end of the web page, it now loads after the div tag elements in the DOM so they can be referenced in the JavaScript and available in memory.

I hope this makes sense and that it helps somebody! 🙂

~Cyber Abyss