How can you retrieve the component's state from a higher level without relying on useContext?

I have a question regarding creating expanding flex cards. I found an example on Codepen that showcases what I'd like to achieve: https://codepen.io/z-/pen/OBPJKK

In my code, I have a component called HomeButtons that generates these flex cards. Within this component, there is a smaller component named ReadMore. Inside ReadMore, I have a useState hook that allows me to toggle each button individually by adding or removing an active class. When the active class is present, the selected button expands while the others shrink.

My goal is to access the state of ReadMore outside of its subcomponent so that I can write a function to remove the active class from a card when another is clicked:

function setToInactive() {
  if (readMore(true)) {
    readMore(false)
  }
}

How can I retrieve the state of ReadMore outside of the subcomponent? Do I need to utilize useContext? I've tried various approaches without success. Is it possible to pass the ReadMore state as a prop to the ReadMore component instead? Thank you!

import React, { useState } from 'react';
import '../style/catalogue.scss';
import collectionsItems from '../Components/collectionsItemsData';
import { Link } from "react-router-dom";

const HomeButtons = ({}) => {

  function ReadMore() {
    const [readMore, setReadMore] = useState(false);

    function toggleSetReadMore() {
      setReadMore(!readMore);
    }

    return (
      <p className='showmore' onClick={toggleSetReadMore} className={readMore ? "collection-item active" : "collection-item"}>TOGGLE BUTTON</p>
    )
  }

  return (
    <div>
      {collectionsItems.map((collectionItem) => {
        const { id, category, img } = collectionItem;
        
        return (
          <article key={id}>
            <img className="item-img" src={img} alt=''/>
            <ReadMore />
            <Link to={`/${category}`} className="item-title">{category}</Link>
          </article>
        )
      })}
    </div>
  );
}

export default HomeButtons;

Answer №1

To address your issue, start by moving the ReadMore component outside of the function. Additionally, consider lifting state up as a solution (https://reactjs.org/docs/lifting-state-up.html). As only one item can be open at a time, you can implement something like this:

function ReadMore({ isOpened, setOpened }) {
  return (
    <p
      onClick={setOpened}
      className={isOpened ? "collection-item active" : "collection-item"}
    >
      TOGGLE BUTTON
    </p>
  );
}

const HomeButtons = () => {
  const [openedItemId, setOpenedItemId] = useState(null);

  return (
    <div>
      {collectionsItems.map((collectionItem) => {
        const { id, category, img } = collectionItem;
        return (
          <article key={id}>
            <img className="item-img" src={img} alt="" />
            <ReadMore
              isOpened={openedItemId === id}
              setOpened={() => setOpenedItemId(id)}
            />
            <Link to={`/${category}`} className="item-title">
              {category}
            </Link>
          </article>
        );
      })}
    </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

Javascript recursive method for fetching data entries

Seeking a solution to retrieve interconnected records based on a parent column, where the relation can be one or many on both ends. After attempting a recursive function without success, I found my code became overly complex and ineffective. Is there a st ...

Updating a select menu with AJAX without the need for a <div> tag within the form

Utilizing an ajax call to dynamically update a select menu is a common practice. The ajax call fetches the options from a separate .php file and populates the select menu accordingly. Below is the code snippet for inserting the dynamic content using JavaS ...

Is there a way to monitor network requests (for debugging purposes) in React Native specifically on a Windows platform?

I've come across several solutions about viewing network requests in React Native on Mac OS, but I need help with debugging on Windows. Can anyone guide me on how to achieve this? ...

Mastering the complexities of Javascript, AJAX, and PHP intertwined

Hello everyone, I'm currently working on a website in Codeigniter and I have a form that I submit using PHP, which works perfectly. However, I also have a small dropdown menu on the side of my page that allows users to jump between pages by clicking o ...

Tips for altering the color of a specific bar in the Material UI BarChart component

I have implemented the following code to generate a Graph: const namesArray = Object.values(tableData).map(item => item.name); const valuesArray = Object.values(tableData).map(item => item.value); return ( <Box> <SimpleCard ti ...

What is the best way to pass an object as a parameter?

I'm facing an issue passing my lineChart object into the data param. Even though I have defined it and it is returning values, it still shows as undefined. Can someone provide assistance? if(!createdIssueslength ){ return null } else { c ...

The correct method for including a CSS file in a Vue.js application

How can external CSS files be properly added in a Vue.js Application? I have come across multiple methods for adding CSS files in a Vue.js Application. One suggestion is to use the following code: <link rel="stylesheet" type="text/css" href="/static/b ...

Is there a way to remove backdrop-filter: blur effect from elements within a div?

Having an issue with a CSS property. I have designed a modal that includes inputs and labels, and I want to blur the background content. However, the problem I am facing is that the blur effect is also being applied to all elements inside the container, in ...

I can't seem to get the dropdown list to appear. What could be the issue?

I'm currently trying to create a pure CSS dropdown menu on hover by following this tutorial. However, despite multiple attempts, I'm still stuck and in need of some clear explanations for my issue. <div class="navbar"> ...

From Figma prototype to React component transformation

Currently, I possess a variety of React components such as tables, buttons, pagination, and more. I am now exploring the idea of developing a Figma plugin that can automatically generate web pages (React class components) based on a Figma design, using m ...

Is there a way I can modify the display setting to show 4 slides per view?

var swiper = new Swiper(".new-arrival", { slidesPerView: 4, centeredSlides: false, spaceBetween: 30, autoplay: { delay: 5500, disableOnInteraction: false, }, pagination: { el: ".swiper-pagination", type: &qu ...

Information derived from a provided URL

I am currently developing a Spotify stats app, and I am facing an issue with creating a context to store the token provided by the app in the URL when a user logs in. TokenContext.js: import React, { useEffect, useState } from "react"; // token ...

Issue: [Issue: ENOENT: the file or directory './1695556319341.mp3' does not exist]

I am currently facing an issue while trying to convert an mp4 file to an mp3 file and then uploading it directly to Firebase storage without saving it locally on my machine. The error I encounter is "Error: [Error: ENOENT: no such file or directory, open ...

Incorporating SASS/SCSS syntax within the <style> element

Can I include SASS/SCSS syntax directly in an .html file within a style tag? I'm interested in defining a variable within the .html file and then utilizing it in a .sass file. ...

Search for documents using jQuery on the page

Here is the layout of a page: HTML <div class="alert alert-dismissable"> <div class="form-group text-center"> <div id="Section"> <div class="row"> <div class="col-md-12"> ...

Struggling to locate div#ID from the loaded fixtures with the Jasmine JS Framework

I successfully loaded my fixtures by using the following code: var fixture = loadFixtures("path/fixture.html"); Now, I am attempting to identify a specific DIV element with the ID #ID using the script below: expect(fixture.find('DIV#ID')).toBe ...

What is the best way to update an object within a deeply nested array of objects using lodash?

I am facing a challenge in my React JS application where I have an array of objects that I need to dynamically modify. Here is the structure of my array : sections: [ { id: 'e9904688-fd8a-476d-8f46-930bc4d888d1', ...

Concealing the ellipsis in the will_paginate function of Rails

I'm currently utilizing will_paginate to manage a large number of values, but I am struggling to find a way to hide the "..." portion and the page numbers following it. Here is my current setup: https://i.stack.imgur.com/f2Tt8.jpg However, what I wou ...

Sass Alert: The mixin called roboto-family is missing from the stylesheet. Trace: Problem detected in src/pages/forms/forms.scss at

Greetings, I am diving into the world of Ionic for the first time. Recently, I embarked on a new project in Ionic and decided to integrate a theme. To do so, I copied an .html file, an .scss file, and also created a .ts file. Forms.html <!DOCTYPE html ...

The React app I've been working on has a tendency to unexpectedly crash when reloading the code from time

Dealing with a frustrating issue here. I've been working on an app and for the past few weeks, it keeps crashing unexpectedly. It seems to happen more frequently after saving my code to trigger a reload, but it can also just crash randomly while navig ...