What is the best way to update a targeted component in React when triggered by an event handler?

Your goal may seem straightforward, but getting a reference to a specific component using this is proving to be tricky.

Here we have our App.js file:

import React, { Component } from 'react';
import CoolBox from './coolBox.js';
import './App.css';

    class App extends Component {

      changeColor(){
        $(this).css('background','blue');
      }

      render() {
        return (
          <div className="App">
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
            <CoolBox changeColor={function(){ this.changeColor() }.bind(this)} />
          </div>
        );
      }
    }

    export default App;

Next, let's take a look at CoolBox.js which represents a simple box with a red background:

import React, { Component } from 'react';
import $ from 'jquery';

class CoolBox extends Component {

  render() {
    return (
      <div onClick={this.props.changeColor} className="box"></div>
    );
  }
}

export default CoolBox;

This is what the result should resemble: https://i.sstatic.net/wu9pt.png

The objective here is that when clicking on any of the three boxes, only the background color of the selected box changes. Unfortunately, it seems that referencing $(this) is not working as intended within React. So, the question remains: How can we accomplish this basic functionality in React?

Answer №1

You can achieve this without using jQuery. There are various methods to reference components in the DOM and different patterns for handling controlled and uncontrolled components that you should familiarize yourself with.
Here is a simple starting solution for you to try out.
When working with event handlers, you can access the event as an argument. For example, in the function changeColor(e), e represents the object containing information about the event, including the target (which refers to the specific div clicked in your case).
In your App.js file, you can implement this like so:

class App extends React.Component {
            constructor(props){
        super(props);
        this.changeColor = this.changeColor.bind(this);
      }
      changeColor(e){
        e.target.style.background = "blue";
      }

      render() {
        return (
          <div className="App">
            <CoolBox changeColor={this.changeColor} />
            <CoolBox changeColor={this.changeColor} />
            <CoolBox changeColor={this.changeColor} />
          </div>
        );
      }
    }  

A quick note:
As you can observe, I bind the handler in the constructor instead of within the render method. This approach ensures that the handler is only bound once, avoiding unnecessary binding on each render call which would create new instances every time. This optimization contributes to better performance.

Answer №2

this in a React component doesn't refer to the DOM element, but rather to the Component instance. The DOM of a specific component can change unpredictably due to changes in state or props.

@Chris mentioned in the comments above that it's not recommended to use jQuery with React components unless there is a valid reason and you understand what you are doing.

It's advised to utilize Component state to define your requirements and then represent the component's state in your render() method.

For illustration:

class FancyBox extends React.Component {
  
  constructor(...args) {
    super(...args);
    this.state = {
      theme: 'light'
    };
    
    this.toggleTheme = this.toggleTheme.bind(this);
  }
  
  toggleTheme() {
    this.setState({
      theme: this.state.theme === 'light' ? 'dark' : 'light'
    });
  }
  
  render() {
    return <div 
      onClick={this.toggleTheme} 
      className="box"
      style={{backgroundColor: this.state.theme}}
      ></div>
  }
}


class MainApp extends React.Component {
  render() {
    return (
      <div>
        <FancyBox />
        <FancyBox />
        <FancyBox />
      </div>
    );
  }
}

ReactDOM.render(<MainApp />, document.getElementById('mainapp'));
.box {
  height: 100px;
  width: 100px;
  margin: 10px;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="mainapp"></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

reconfigure keyboard shortcuts in web browser

In the popular web browser Google Chrome, users can quickly jump to the next tab by pressing CTRL + TAB. Is there a way to change or disable this shortcut? The provided code snippet does not seem to work as intended. $(document).keydown(function(e){ ...

How can items be categorized by their color, size, and design?

[{ boxNoFrom: 1, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" { boxNoFrom: 13, boxs: [{…}], color: "ESPRESSO", size: "2X", style: "ZIP UP" }, { boxNoFrom: ...

The declaration file for the module could not be located as '@types/...@latest' is not available in the npm registry

After installing react-pivottable, I encountered an error when attempting to import it: import PivotTableUI from 'react-pivottable'; The error message in vscode warned: Could not find a declaration file for module 'react-pivottable'. ...

Updating with Setstate

Refreshing the page with Setstate, registering twice and doubling the count of both heads and tails counter every time on click instead of adding just +1 class CoinFlip extends Component { constructor(props) { super(props); ...

Having trouble running "npm run start" after copying files to server with NextJS and Express?

While developing a NextJS application, I encountered an issue when attempting to deploy it with Express. When I do not use Express, deploying the production files to my server works smoothly. However, as soon as I integrate Express into the application, I ...

Displaying content on a webpage using PHP, AJAX, and HTML

Looking to update my current form setup. I have a basic Form below: <form action="" method="POST"> <input type="button" value="Generate Numbers" onclick="on_callPhp1()"/> </form> Accompanied by this javascript code: <script type="te ...

Creating a dynamically generated sitemap route in NextJS

I am struggling to generate a dynamic router for the sitemaps that are accessible via the following URLs: example.com/sitemap-0.xml example.com/sitemap-1.xml My attempt was to create a page using the following file structure: [sitemap].xml.js Unfortunat ...

Combining Extjs combo with autocomplete functionality for a search box, enhancing synchronization capabilities

When using autocomplete search, I've encountered an issue. If I type something and then make a mistake by deleting the last character, two requests are sent out. Sometimes, the results of the second request come back first, populating the store with t ...

The tabs in Bootstrap 5.0 seem to be malfunctioning as they are displaying different tab information when clicked on

Trying to integrate Bootstrap5.0 tabs in the code below, but encountering issues. The tabs are visible, but upon clicking them, incorrect tab information is displayed. For instance, clicking on the profile tab should only display "clicked profile", but ins ...

Encountering issues while running the npm build command due to exporting async functions in React

In my React project, I am utilizing async functions and have created a file named apiRequest.js structured like this: const axios = require('axios'); const serverURL = "http://localhost:8080" getInfo = async function ({email}) { try { r ...

The button's background color remains the same even after clicking on it

In my exploration of Vue.js, I decided to create a simple project to grasp the concept of class binding. I wanted to add functionality to each button component, so that when a button is clicked, it would change its color or background color to something ot ...

Issue with Bootstrap carousel controls malfunctioning and delayed transition to the next slide

I am facing some difficulties with my carousel. The transition to the next slide is taking longer than usual, and even when I try using the controls, they do not respond no matter how many times I click on them. I have followed all the instructions in the ...

Activate dark mode automatically in material-ui

According to the official documentation: The documentation mentions that a dark mode theme will be automatically generated and reflected in the UI, but I am encountering issues with it. Dependencies: "@emotion/styled": "^11.0.0", ...

Utilizing Threejs to implement dynamic text labels

Recently, after reading a discussion on stackoverflow, I decided to incorporate labels into my canvas. To achieve this, I created a second scene and camera to overlay the labels on top of the first scene. this.sceneOrtho = new THREE.Scene();//for labels t ...

Are you delving into the realm of reduce functions in order to grasp the intric

Currently following this particular tutorial where they utilize the reduce method to transform an Array<Student> into a { [key: string]: Array<string | number> }. The tutorial includes this expression that caught my attention. It's quite n ...

Experiencing an "isTrusted" error while working with the GLTFLoader

QUERY: All was running smoothly: I successfully transformed my FBX files to GLTF in the /GLTF/ directory. Unfortunately, after noticing missing geometry in some converted files, I attempted another conversion of the FBX files, this time to /TEST/. Unexp ...

Problems with implementing JavaScript code in a WebView

I am currently working on an android WebView project where I have managed to change the background color to orange with this code snippet. @Override public void onPageFinished(WebView view, String url) { wv.loadUrl("jav ...

Personalizing the styles of child components using parent component and JSS

Currently, I am deep into a project where all the styles are declared in JSS. While many articles and library docs tout the benefits of encapsulating styles in JSS, I find myself struggling to customize them, especially when it involves styling that relies ...

PHP failing to send emails from my website

My website has a contact form, but the form data is being appended to the URL and the JSON is not being sent to the PHP mail handler. Below you can find my code for the form. HTML <form novalidate="novalidate" style="width:60%;margin-left:auto;margin- ...

How to change a string from utf-8 to iso-8859-1 using Javascript

Although it may seem unpleasant, it is essential. I am facing an issue with a HTML form on my website that uses utf-8 charset but is sent to a server operating with iso-8859-1 charset. The problem arises when the server fails to interpret characters commo ...