vogel22
vogel22

Reputation: 15

React - add active class on click

I've read and tried many solutions already, but I'm new to React and I cannot figure out how to add class "active" when the div is clicked. Can someone please explain that to me? Here is my code..I'd like to add "active" to "div className='section-chat'" when clicked and remove it from the element that was active previously. I'm including two files I have so far. The biggest problem for me is that I have data from an object and I'm not sure how to combine all of the things together if I try to add a class toggle.

import React from "react";
import "./Group-Chat.scss";

export const Chats = ({
  name,
  avatar,
  time,
  status,
  message,
  phone,
  notification,
  menu,
}) => {
  if (!menu)
    return (
      <div className="section-chat">
        <div className="chat">
          <div className="chat-left">
            <div className="chat-photo">
              <img src={avatar} alt="" />
            </div>
            <div className="chat-middle">
              <div className="chat-middle-top">
                <img src={status} alt="" />
                <span className="group-name">{name}</span>
                <div className="chat-middle-bottom">{message}</div>
              </div>
            </div>
          </div>
          <div className="chat-right">
            <div className="chat-time">{time}</div>
            <div className="right-chat-icons">
              <div className="phone">
                <img src={phone} alt="" />
              </div>
              <div className="icon">
                <img src={notification} alt="" />
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  else if (!notification)
    return (
      <div className="section-chat">
        <div className="chat">
          <div className="chat-left">
            <div className="chat-photo">
              <img src={avatar} alt="" />
            </div>
            <div className="chat-middle">
              <div className="chat-middle-top">
                <img src={status} alt="" />
                <span className="group-name">{name}</span>
                <div className="chat-middle-bottom">{message}</div>
              </div>
            </div>
          </div>
          <div className="chat-right">
            <div className="chat-time">{time}</div>
            <div className="right-chat-icons">
              <div className="icon">
                <img src={phone} alt="" />
              </div>
              <div className="icon">
                <img src={menu} alt="" />
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  else if (!notification && !menu)
    return (
      <div className="section-chat">
        <div className="chat">
          <div className="chat-left">
            <div className="chat-photo">
              <img src={avatar} alt="" />
            </div>
            <div className="chat-middle">
              <div className="chat-middle-top">
                <img src={status} alt="" />
                <span className="group-name">{name}</span>
                <div className="chat-middle-bottom">{message}</div>
              </div>
            </div>
          </div>
          <div className="chat-right">
            <div className="chat-time">{time}</div>
            <div className="right-chat-icons">
              <div className="icon">
                <img src={phone} alt="" />
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  else
    return (
      <div className="section-chat">
        <div className="chat">
          <div className="chat-left">
            <div className="chat-photo">
              <img src={avatar} alt="" />
            </div>
            <div className="chat-middle">
              <div className="chat-middle-top">
                <img src={status} alt="" />
                <span className="group-name">{name}</span>
                <div className="chat-middle-bottom">{message}</div>
              </div>
            </div>
          </div>
          <div className="chat-right">
            <div className="chat-time">{time}</div>
            <div className="right-chat-icons">
              <div className="icon">
                <img src={phone} alt="" />
              </div>
              <div className="icon">
                <img src={notification} alt="" />
              </div>
              <div className="icon">
                <img src={menu} alt="" />
              </div>
            </div>
          </div>
        </div>
      </div>
    );
};```



    import React from "react";
    import "./Group-Chat.scss";
    import { chatData } from "../data";
    import { Chats } from "./Chat-container";
    
    export const DirectChats = () => {
      return (
        <>
          <DirectChatHeader />
          <div className="chat-container" id="section">
            {chatData.map((data, key) => {
              return (
                <div key={key}>
                  <Chats
                    key={key}
                    name={data.name}
                    avatar={data.avatar}
                    time={data.time}
                    status={data.status}
                    message={data.message}
                    phone={data.phone}
                    notification={data.notification}
                    menu={data.menu}
                  />
                </div>
              );
            })}
          </div>
        </>
      );
    };
    
    const DirectChatHeader = () => {
      return (
        <div className="section-title">
          <span>Direct Messages</span>
          <div className="plus-icon" id="container">
            <img src={require("../images/icons/plus.png")} alt="" />
          </div>
        </div>
      );
    };

Upvotes: 0

Views: 3755

Answers (2)

Tomer Almog
Tomer Almog

Reputation: 3868

This can be cleaner, but just so you get it working. You want to use a dynamic class and useState to change it: Try this:

    import React, { useState } from "react";
    import "./Group-Chat.scss";

    export const Chats = ({
      ...
    }) => {
      const [chatClassName, setChatClassName] = useState('section-chat');

      const toggleClass = () => {
        if (chatClassName === 'section-chat') {
            setChatClassName('section-chat active');
        } else {
            setChatClassName('section-chat');
        }
      }
      if (!menu)
        return (
          <div className={chatClassName} onClick={toggleClass}>

Or if you want to keep the class names in the jsx code (preferred): (notice the extra space before the ' active')

    import React, { useState } from "react";
    import "./Group-Chat.scss";

    export const Chats = ({
      ...
    }) => {
      const [active, setActive] = useState(false);

      const toggleClass = () => {
        setActive(!active);
      }
      if (!menu)
        return (
          <div className={`section-chat ${active? ' active' : ''}`} onClick={toggleClass}>

Upvotes: 2

tay_thomp
tay_thomp

Reputation: 239

You need to hold the active state in your component. For example:

const Chat ({  name,
  avatar,
  time,
  status,
  message,
  phone,
  notification,
  menu,
}) => {
const [active, setActive] = React.useState(false)
return (
 // div you want to change
 <div className={active ? "section-chat-active" : "section-chat"}>{/* child components here */}</div>
// ...rest of component
 )
}

In the case that you want to toggle classes for multiple divs, you need to track them via some identifier (like id) and then append the active class based on whether or not the id is in the active state.

Upvotes: 1

Related Questions