Taming the Globals: Best Practices for Component-Based Navigation in React Router

2024-07-27

  • In JavaScript, certain built-in objects like window, document, and browser APIs (like alert or prompt) are considered "globals" because they're accessible from anywhere in your code.
  • However, using these globals directly can make code less maintainable, testable, and prone to errors due to unintended side effects or name conflicts.

"No Restricted Globals" Rule

  • This is a linting rule (often enforced by tools like ESLint) that helps prevent developers from directly accessing these globals.
  • The goal is to encourage writing cleaner, more modular, and testable code.

Alternatives in React and React Router

  • React provides component-specific hooks and props to manage state and interactions within your application. For instance, use useState to manage internal component state, and pass data as props from parent to child components.
  • React Router offers hooks like useHistory (in older versions) or useNavigate (in newer versions) for programmatic navigation within your app, instead of relying on the global window.history object. By using these hooks, React Router manages the navigation state and URL updates.

Benefits of Avoiding Globals

  • Improved Maintainability: Code is easier to understand and modify without worrying about hidden dependencies on globals.
  • Enhanced Testability: Components can be isolated and tested independently without relying on external state or side effects introduced by globals.
  • Reduced Risk of Errors: Accidental modifications to globals can be prevented, leading to more stable and reliable code.

Example (React Router Navigation with useNavigate):

import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const navigate = useNavigate();

  const handleClick = () => {
    navigate('/new-page'); // Programmatic navigation using useNavigate
  };

  return (
    <button onClick={handleClick}>Go to New Page</button>
  );
}



Without no-restricted-globals:

// This might trigger the "no-restricted-globals" rule
function MyComponent() {
  const currentPath = window.location.pathname; // Using global `window.location`
  // ...
}

With useLocation:

import { useLocation } from 'react-router-dom';

function MyComponent() {
  const location = useLocation();
  const currentPath = location.pathname; // Using `useLocation` hook
  // ...
}

Programmatic Navigation (Using useNavigate):

// This might trigger the "no-restricted-globals" rule
function MyComponent() {
  const handleClick = () => {
    window.location.href = '/new-page'; // Using global `window.location`
  };
  // ...
}

With useNavigate:

import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const navigate = useNavigate();

  const handleClick = () => {
    navigate('/new-page'); // Using `useNavigate` hook
  };
  // ...
}

Accessing DOM Elements (Avoiding document):

// This might trigger the "no-restricted-globals" rule
function MyComponent() {
  const titleElement = document.getElementById('my-title');
  // ...
}

In this specific case, directly accessing the DOM might not be the best approach for React components. However, if necessary, alternative solutions exist:

  • Refs: Create a React ref using useRef hook and attach it to the desired element. Access it within the component using the ref object.
  • Third-party Libraries: Consider libraries like react-dom or styled-components for more controlled DOM manipulation within React.



  • Context API: If location information needs to be shared across multiple components, consider using React's Context API to provide a centralized location object accessible throughout your application.

Programmatic Navigation:

  • React Router v5 useHistory (For Older Versions): While useNavigate is preferred in newer versions, React Router v5 offered the useHistory hook for programmatic navigation:
import { useHistory } from 'react-router-dom';

function MyComponent() {
 const history = useHistory();

 const handleClick = () => {
   history.push('/new-page'); // Using useHistory hook
 };
 // ...
}

Accessing DOM Elements:

  • Controlled Components: For form elements (inputs, selects, etc.), use controlled components where the value is managed by the component's state and reflected in the DOM.
  • Event Delegation: Instead of directly accessing specific elements for event handling, consider using event delegation on parent elements to capture events and conditionally apply logic based on the target element.

Here's an example of controlled components:

function MyComponent() {
  const [inputValue, setInputValue] = useState('');

  const handleChange = (event) => {
    setInputValue(event.target.value);
  };

  return (
    <input type="text" value={inputValue} onChange={handleChange} />
  );
}

javascript reactjs react-router



Enhancing Textarea Usability: The Art of Auto-sizing

We'll create a container element, typically a <div>, to hold the actual <textarea> element and another hidden <div>. This hidden element will be used to mirror the content of the textarea...


Alternative Methods for Validating Decimal Numbers in JavaScript

Understanding IsNumeric()In JavaScript, the isNaN() function is a built-in method used to determine if a given value is a number or not...


Alternative Methods for Escaping HTML Strings in jQuery

Understanding HTML Escaping:HTML escaping is a crucial practice to prevent malicious code injection attacks, such as cross-site scripting (XSS)...


Learning jQuery: Where to Start and Why You Might Ask

JavaScript: This is a programming language used to create interactive elements on web pages.jQuery: This is a library built on top of JavaScript...


Alternative Methods for Detecting Undefined Object Properties

Understanding the Problem: In JavaScript, objects can have properties. If you try to access a property that doesn't exist...



javascript reactjs react router

Unveiling Website Fonts: Techniques for Developers and Designers

The most reliable method is using your browser's developer tools. Here's a general process (specific keys might differ slightly):


Ensuring a Smooth User Experience: Best Practices for Popups in JavaScript

Browsers have built-in popup blockers to prevent annoying ads or malicious windows from automatically opening.This can conflict with legitimate popups your website might use


Interactive Backgrounds with JavaScript: A Guide to Changing Colors on the Fly

Provides the structure and content of a web page.You create elements like <div>, <p>, etc. , to define different sections of your page


Understanding the Code Examples for JavaScript Object Length

Understanding the ConceptUnlike arrays which have a built-in length property, JavaScript objects don't directly provide a length property


Choosing the Right Tool for the Job: Graph Visualization Options in JavaScript

These libraries empower you to create interactive and informative visualizations of graphs (networks of nodes connected by edges) in web browsers