Home > Enterprise >  How to independently set a button click in react?
How to independently set a button click in react?

Time:04-29

I am trying to figure out on how to set a button that can independently be disabled when using the .map function. So I created a state whenever the button is clicked, it disables that specific button. However, it only disables all of the buttons which is not what i wanted. Is there a way to make the buttons have their own click event which can be disabled according to the index?

  const [click, setClick] = useState(false);
  const array = ["item 1", "item 2", "item 3"];

  const disableClick = () => {
    setClick(true);
  };
  
  return (
    <div className="App">
      {array.map((item) => (
        <div>
          <h2>{item}</h2>
          {!click ? (
            <button onClick={disableClick}>CLICK {item}</button>
          ) : (
            <button disabled>Button clicked</button>
          )}
        </div>
      ))}
    </div>
  );

CodePudding user response:

Disable takes an arguments you can supply it with <button disabled={click? true:false} >Button clicked</button>

Is there a way to make the buttons have their own click event which can be disabled according to the index?

Yes, How? instead of setting the click state to true or false, we can set it to contain name of the button const [disabledBtn, setDisabledBtn] = useState("item 1"); and then we can compare it with the items from the map. <button disabled={disabledBtn == item ? true:false} >Button clicked</button>

This code render the buttons with the first button disabled by default, if the user clicks on one of the other available buttons it will trigger rerender and that btn will be disabled. You should add a key to your childern components to maintain uniqueness between renderings.

This code snippet should answer your question

const [disabledBtn, setDisabledBtn] = useState("item 1");
const array = ["item 1", "item 2", "item 3"];

const handleDisableClick = (item) => {
  setDisabledBtn(item);
};

return (
  <div className="App">
    {array.map((item, idx) => (
      <div key={idx}>
        <h2>{item}</h2>
        <button
          disabled={disabledBtn == item ? true : false}
          onClick={() => handleDisableClick(item)}
        >
          Button clicked
        </button>
      </div>
    ))}
  </div>
);

CodePudding user response:

Move the click handler and useState in a separate component.

const ButtonView = (textContent) => {
  const [disabled, setDisabled] = useState(false);

  const onClick = () => {
    setDisabled(true);
  };

  if (disabled) {
    return <button disabled={disabled}>Button clicked</button>;
  }

  return <button onClick={onClick}>CLICK {textContent}</button>;
};

export const View = () => {
  const array = ["item 1", "item 2", "item 3"];
  
  return (
    <div className="App">
      {array.map((item, key) => (
        <div key={key}>
          <h2>{item}</h2>
          <ButtonView textContent={item} />
        </div>
      ))}
    </div>
  );
};

Or do this:

const ButtonView = (textContent) => {
  const [disabled, setDisabled] = useState(false);

  const onClick = () => {
    setDisabled(true);
  };
  const content = disabled ? "Button clicked" : textContent
  return <button disabled={disabled} onClick={onClick}>CLICK {content}</button>;
};

CodePudding user response:

You could store button as an array of objects, with a click state for each, like this:

  const buttons = [
    {
       name: 'item1',
       click: false
    },
    {
       name: 'item2',
       click: false
    },
    {
       name: 'item3',
       click: false
    }
  ]
  const [buttons, setClick] = useState(false);
  

  const disableClick = (e) => {
    //here put a modified copy of the buttons object according to the user's action
    setClick(); 
  };
  
  return (
    <div className="App">
      {array.map((item) => (
        <div>
          <h2>{item.name}</h2>
          {!item.click ? (
            <button onClick={disableClick(item.name)}>CLICK {item.name}</button>
          ) : (
            <button disabled>Button clicked</button>
          )}
        </div>
      ))}
    </div>
  );
  • Related