skip to Main Content

i have a list of divs and buttons associated with them. when i click on any one of the divs,
i want only ONE button, which is associated with that div to be displayed.
however with the code i’ve written all the buttons are displayed upon clicking any one div.

i’ve set a state which prevents displaying of any button in the initial state, and when a div is clicked, i set the state to true, which lets the button element be displayed.

but this method causes all buttons to be shown. how do i fix this?

import React,{useEffect,useState} from 'react';

export function App(props) {

  let [startconv,setStartconv]=useState(false);
  let current=[{name:'yaba1',age:20},{name:'yaba2',age:23}]

  let handleclicker=(o)=>{
    setStartconv(true);
    console.log(o);
  }


  return (
    <div className="online">
      
      {current.map((o) => (
        <div key={o.age}>
          <div className="allonline" style={{ border: 'blue 2px solid', marginBottom: '15px', width: '300px' }} onClick={() => handleclicker(o)}>
            <div className="onlinepfpcont">
              <img alt=" " />
            </div>
            <span className="onlineusername" style={{ color: 'red' }}>{o.name}</span>
          </div>
          {startconv && <button className="startconvobutton" >start {o.name}</button>}
        </div>

      ))}
    </div>
  );
}

2

Answers


  1. Follow the steps below to display one button at a time

    1. keep the state initially empty
    2. add index to the map function
    3. pass the index to the hand click function
    4. set the index to the state from handleclicker function
    5. compare the index with the state

    I’m hoping it works.

     //keep the state initially empty
    let [startconv,setStartconv]=useState();
    let current=[{name:'yaba1',age:20},{name:'yaba2',age:23}]
    
    let handleclicker=(i)=>{
     // set the index to the state
      setStartconv(i);
    }
    
    
    return (
    <div className="online">
     //add index here 
      {current.map((o, i) => (
        <div key={o.age}>
         // pass index to the hand click function
          <div ....... onClick={() => handleclicker(i)}> 
            .........rest of the code ........
          </div>
         // compare the index with the state
          {startconv === i && <button className="startconvobutton" >start {o.name}</button>}
        </div>
    
      ))}
    </div>
    );
    
    Login or Signup to reply.
  2. The issue with your code is that you are using a single state variable startconv to control the visibility of all buttons associated with the divs. As a result, when you set startconv to true on any div click, it affects all buttons because they are all using the same state.

    To fix this and show only the button associated with the clicked div, you can use a separate state variable for each item in the current array. One way to achieve this is by using an object instead of a single boolean for startconv, where the keys represent the unique identifiers of the divs (e.g., age or any other unique ID), and the values represent the visibility state of each button.

    Here’s how you can modify your code:

    import React, { useEffect, useState } from 'react';
    
    export function App(props) {
      const [startconv, setStartconv] = useState({}); // Using an object for individual item states
      const current = [
        { name: 'yaba1', age: 20 },
        { name: 'yaba2', age: 23 }
      ];
    
      const handleclicker = (o) => {
        setStartconv((prev) => ({ ...prev, [o.age]: true })); // Set the specific item's state to true
        console.log(o);
      };
    
      return (
        <div className="online">
          {current.map((o) => (
            <div key={o.age}>
              <div className="allonline" style={{ border: 'blue 2px solid', marginBottom: '15px', width: '300px' }} onClick={() => handleclicker(o)}>
                <div className="onlinepfpcont">
                  <img alt=" " />
                </div>
                <span className="onlineusername" style={{ color: 'red' }}>{o.name}</span>
              </div>
              {startconv[o.age] && <button className="startconvobutton" >start {o.name}</button>}
            </div>
          ))}
        </div>
      );
    }
    

    In this updated code, we use the startconv object to keep track of the visibility of each button associated with the divs. When a div is clicked, we update the state by setting the specific item’s property (e.g., o.age) to true, which causes the corresponding button to be displayed. For all other divs, their associated button remains hidden because their corresponding property in the startconv object is false or undefined.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search