How to use forEach in react js

Issue

I want to create a function which iterate over all element with same class and remove a specific class.

It could be done easily using JavaScript.

const boxes = document.querySelectorAll(".box1");
function remove_all_active_list() {
    boxes.forEach((element) => element.classList.remove('active'));
}

But how can I do this similar thing is ReactJs. The problem which I am facing is that I can’t use document.querySelectorAll(".box1") in React but, I can use React.createRef() but it is not giving me all elements, it’s only giving me the last element.

This is my React Code

App.js

import React, { Component } from 'react';
import List from './List';

export class App extends Component {

    componentDidMount() {
        window.addEventListener('keydown', this.keypressed);
    }

    keypressed = (e) => {
        if (e.keyCode == '38' || e.keyCode == '40') this.remove_all_active_list();
    };

    remove_all_active_list = () => {
        // boxes.forEach((element) => element.classList.remove('active'));
    };

    divElement = (el) => {
        console.log(el);
        el.forEach((element) => element.classList.add('active'))
    };

    render() {
        return (
            <div className="container0">
                <List divElement={this.divElement} />
            </div>
        );
    }
}

export default App;

List.js

import React, { Component } from 'react';
import data from './content/data';

export class List extends Component {
    divRef = React.createRef();

    componentDidMount() {
        this.props.divElement(this.divRef)
    }

    render() {
        let listItem = data.map(({ title, src }, i) => {
            return (
                <div className="box1" id={i} ref={this.divRef} key={src}>
                    <img src={src} title={title} align="center" alt={title} />
                    <span>{title}</span>
                </div>
            );
        });
        return <div className="container1">{listItem}</div>;
    }
}

export default List;

Please tell me how can I over come this problem.

Solution

The short answer

You wouldn’t.

Instead you would conditionally add and remove the class to the element, the component, or to the collection.map() inside your React component.

Example

Here’s an example that illustrates both:

import styles from './Example.module.css';

const Example = () => {
  const myCondition = true;

  const myCollection = [1, 2, 3];

  return (
    <div>
      <div className={myCondition ? 'someGlobalClassName' : undefined}>Single element</div>
      {myCollection.map((member) => (
        <div key={member} className={myCondition ? styles.variant1 : styles.variant2}>
          {member}
        </div>
      ))}
    </div>
  );
};

export default Example;

So in your case:

  • You could pass active prop to the <ListItem /> component and use props.active as the condition.

  • Alternatively you could send activeIndex to <List /> component and use index === activeIndex as the condition in your map.

Explanation

Instead of adding or removing classes to a HTMLElement react takes care of rendering and updating the whole element and all its properties (including class – which in react you would write as className).

Without going into shadow dom and why react may be preferable, I’ll just try to explain the shift in mindset:

Components do not only describe html elements, but may also contain logic and behaviour. Every time any property changes, at the very least the render method is called again, and the element is replaced by the new element (i.e. before without any class but now with a class).

Now it is much easier to change classes around. All you need to do is change a property or modify the result of a condition (if statement).

So instead of selecting some elements in the dom and applying some logic them, you would not select any element at all; the logic is written right inside the react component, close to the part that does the actual rendering.

Further reading

https://reactjs.org/docs/state-and-lifecycle.html

Please don’t hessitate to add a comment if something should be rephrased or added.

Answered By – Webber

Answer Checked By – Robin (AngularFixing Admin)

Leave a Reply

Your email address will not be published.