Identify the element with the active class name as the primary focus

Can anyone assist with this issue? Below is an example of the code I am working with:

import React, { useRef, useEffect } from "react";

function App() {
  const inputRef = useRef(null);

  useEffect(() => {
    const testElement = document.querySelectorAll(".active");
    testElement.length > 0 && inputRef.current.focus();
   }, []);

  return (
    <div style={{width: 200, height: 190, display: "flex", flexDirection: "column", justifyContent: "space-between"}}>
      <input id={1} type="text" ref={inputRef} />
      <input id={2} type="text" ref={inputRef} />
      <input id={3} className={"active"} type="text" ref={inputRef} />
      <input id={4} type="text" ref={inputRef} />    
    </div>
  );
}

export default App;

I am facing a challenge in focusing on a specific element that has a particular class name. In this case, the element is an input field with the id "3" and a class name of "active". However, the focus is currently being set to the input element with id "4" instead.

Your help is greatly appreciated.

Answer №1

In React, it's best practice to control the .active class by updating the state/properties. Whether it's through an action like a click event or directly changing the state, the focus can also be controlled (as shown in the 3rd example). It's important to avoid direct DOM manipulation.

If multiple elements share the same ref and they replace each other during renders, only the last item will receive focus. To address this with refs, you should use an array for inputRef and have each input add itself to the array using a function ref.

You can then iterate through the items in a useEffect hook, find the one with the .active class, and set focus on it.

const { useRef, useEffect } = React;
function App() {
  const inputRef = useRef([]);
  useEffect(() => {
    for(const r of inputRef.current) {
      if(r.classList.contains('active')) {
        r.focus();
        return;
      }
    }
   }, []);
   const addRef = r => inputRef.current.push(r)
  return (
    <div style={{width: 200, height: 190, display: "flex", flexDirection: "column", justifyContent: "space-between"}}>
      <input id={1} type="text" ref={addRef} />
      <input id={2} type="text" ref={addRef} />
      <input id={3} className={"active"} type="text" ref={addRef} />
      <input id={4} type="text" ref={addRef} />    
    </div>
  );
};
ReactDOM.render(
  <App />,
  root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

Alternatively, if you're already manipulating the DOM, you can directly use document.querySelector(). While not the recommended React approach, it is simpler and doesn't require refs:

const { useEffect } = React;

function App() {
  useEffect(() => {
    const active = document.querySelector('.active');
    
    if(active) active.focus();
   }, []);

  return (
    <div style={{width: 200, height: 190, display: "flex", flexDirection: "column", justifyContent: "space-between"}}>
      <input id={1} type="text" />
      <input id={2} type="text" />
      <input id={3} className={"active"} type="text" />
      <input id={4} type="text" />    
    </div>
  );
};
ReactDOM.render(
  <App />,
  root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

If you're working with a model passed via state/props, you can utilize the state/properties to manage focus and class (see comments in the code):

const { useRef, useEffect } = React;
// Each item renders it's own input, and focuses the item if the selected prop is true
const Item = ({ selected }) => {
  const inputRef = useRef(null);
  useEffect(() => {
    if(selected) inputRef.current.focus();
  }, [selected]);
    
  return (
    <input className={selected ? 'active' : ''} type="text" ref={inputRef} />
  );
};

// App renders a list of items
const App = ({ items }) => (
  <div style={{width: 200, height: 190, display: "flex", flexDirection: "column", justifyContent: "space-between"}}>
  {items.map(item => (
    <Item key={item.id} {...item} />
  ))}
  </div>
);
const items = [{ id: 1 }, { id: 2 }, { id: 3, selected: true }, { id: 4 }];
ReactDOM.render(
  <App items={items} />,
  root
);
.active {
  outline: 1px solid red;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

HTML list with clickable elements for querying the database and displaying the results in a <div> element

Patience please; I am a newcomer to StackOverflow and this is my inaugural question. Struggling with writing an effective algorithm, I wonder if my attempts to "push" it forward are causing me to complicate what should be a straightforward concept, or if i ...

Tips for enabling unrestricted unencoded HTML in XmlNode or XmlElement with XmlSerializer

Looking for a solution to generate an XML element that can handle a string of text containing HTML or other valid XML elements. Here's an example: "Test text with <strong>custom nodes</strong> that shouldn't be encoded" I've at ...

Exploring the benefits of using Div and semantic elements in web

After spending more than two months learning HTML, I still find myself uncertain about the most practical coding approach. Despite knowing that it's important not to overthink it, I often wonder if I should stick with simplicity or add extra elements ...

Issue with safeAreaView measurement in React Native is preventing desired functionality

One issue I am currently facing is the necessity to measure the View element using the standard measure function. However, a complication arises when the same function is utilized within the context of a SafeArea. const headerRef = useRef(null); ... use ...

The infinite scroll feature seems to be malfunctioning in my react.js project. Despite implementing the infinite scroll component, the images from the next page are not being

I recently started learning React.js and I'm trying to implement infinite scrolling to fetch more images from the Flicker API, but for some reason, it's not working as expected. Currently, I'm using Material UI along with the Infinite Scrol ...

What is the best way to center an image and text vertically using bootstrap?

I'm currently working on a Bootstrap website and have reached a section where I want to display text on the left and an image on the right. While I've managed to achieve this layout, I'm struggling with vertically centering the image. Despit ...

How can an SVG circular progress bar be created using stroke dasharray?

Can anyone help me with adding dashes between the line in this progress bar I'm trying to recreate? Any suggestions would be greatly appreciated. This is my progress so far: I have been using the react-move library to animate the clock <CircularP ...

Struggling to dynamically append additional textboxes to a <div> element using JavaScript

After spending over 12 hours on this problem, I am completely stuck and frustrated. I have tried countless variations and sought out other solutions to no avail. It should be a simple task. My project involves using JQueryMobile 1.2 along with its dependen ...

Utilize Python and BeautifulSoup for parsing HTML with multiple tags and classes

I am currently attempting to navigate through a complex HTML structure. Here is the snippet of the HTML code: <div class="example one"> <ol class="example two"> <li class="example three"> My object ...

Leverage JSON files for pagination in NextJS

I am currently developing a science website where the post URLs are stored in a static JSON file. ScienceTopics.json- [ { "Subject": "Mathematics", "chapters": "mathematics", "contentList": [ ...

Help! The CSS height property is not working properly and I'm not sure how to resolve

I'm facing an issue with the height property of a specific div and I can't seem to fix it. SCSS: .security{ border: 3px #1D3176 solid; display: flex; h2{ position: ...

What is the reason behind being unable to register two components with the same name using React Hook Form?

I have encountered an issue while using the useForm hook from React Hook Form library. Due to the specific UI library I am using, I had to create custom radio buttons. The problem arises when I try to register two components with the same name in the form ...

Challenges with Type Aliases when Using Typescript with MaterialUI Icons

I am searching for a way to dynamically incorporate Material UI icons into my code based on specific strings found in a configuration file. I have come across an approach that seems promising: https://medium.com/@Carmichaelize/dynamic-tag-names-in-react-a ...

Encountering an error while configuring webpack with ReactJS: Unexpected token found while

I'm attempting to update the state of all elements within an array in ReactJS, as illustrated below. As a newbie to this application development, it's challenging for me to identify the mistake in my code. closeState(){ this.state.itemList.f ...

The Web Browser is organizing CSS elements in an alphabetized sequence

map.css({ 'zoom': zoom, 'left': map.width()/(2*zoom) - (point[0]/100)*map.width(), 'top': map.height()/(2*zoom) - (point[1]/100)*map.height() Upon observation, it appears that Chrome adjusts the map zoom first be ...

Ajax calls within nested functions are not being executed in the correct sequence

Currently, I am utilizing the geonames API to retrieve geographical information. My objective is to extract the names of states within a country using the getStateInfo function and subsequently obtain a list of cities in each state through the getCityInfo ...

Adding a class to a clicked button in Vue.js

A unique function of the code below is showcasing various products by brand. When a user clicks on a brand's button, it will display the corresponding products. This feature works seamlessly; however, I have implemented a filter on the brands' lo ...

Encountering difficulties connecting to the database within Vue data tables

My php script was working fine with vuetify data, but now every page is showing the error message: Your search for "{{ search }}" found no results. It seems like this issue occurs when the script cannot fetch data from the database. Here is my d ...

What could be causing an issue with exporting the ListItem component in Material-UI?

Here is an example where I am attempting to export the ListItem component from Material-UI. import ListItem, { ListItemProps } from '@material-ui/core/ListItem'; export const MyListItem = (props: ListItemProps) => ( <ListItem {...prop ...

"Managing output buffers, styling with CSS, and sending emails with PHP

I am currently using a script to send emails that result in a couple of HTML tables: $from = "example.com <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82efebe7ef83898ce0ede1e9e3e6d2edeee8">[email protected]</a ...