user13427179
user13427179

Reputation:

on button click change text value

I am beginner in react js, i am stuck in a problem when i click on any color i want to change hex value to display "copied" as text

you can see below img as an example https://ibb.co/XWVzmwr

import React from 'react';

const Red = () =>{

    const colors = {
        color21 : '#FF3031',
        color22 : '#E84342',
        color23 : '#E44236',
        color24 : '#D63031',
        color25 : '#EC4849',
        color26 : '#E8290B',
        color27 : '#E8290B',
        color28 : '#AE1438',
        color29 : '#FF4848',
        color30 : '#FF362E', 
    }

    return (
        <div>
            <h1 className='r-color-title'>Red Color</h1>
            <div className='container-fluid'>
                {Object.entries(colors).map(([id, color]) => 
                    <div className='div-style' id={id} onClick={()=>navigator.clipboard.writeText(color)}>{color}</div>
                )}
            </div>   
        </div>
    )
}

export default Red;

Upvotes: 1

Views: 69

Answers (4)

Apostolos
Apostolos

Reputation: 10463

As an alternative to Sachin's answer, what you can do is to store the selected hex (or id, you decide) at your component's inner state and then handle it accordingly at render

const Red = () => {

 const [selectedHex, setSelectedHex] = useState(null)

  const colors = {
    color21 : '#FF3031',
    color22 : '#E84342',
    color23 : '#E44236',
    color24 : '#D63031',
    color25 : '#EC4849',
    color26 : '#E8290B',
    color27 : '#E8290B',
    color28 : '#AE1438',
    color29 : '#FF4848',
    color30 : '#FF362E',
  }

  return (
    <div>
      <h1 className='r-color-title'>Red Color</h1>
      <div className='container-fluid' style={{display: "flex"}}>
        {Object.entries(colors).map(([id, color]) =>
          <div className='div-style' id={id} style={{background: color, width: 100, height: 100}} onClick={() => {
            navigator.clipboard.writeText(color)
            setSelectedHex(color)
          }}
          >{color === selectedHex ? "Copied" : color}</div>
        )}
      </div>
    </div>
  )
}

Upvotes: 0

gazdagergo
gazdagergo

Reputation: 6691

You can simply use the css 'focus' pseudo selector for the "copied" text display, and keep react for the business logic.

button {
  background: orange;
  display: inline-flex;
  width: 70px;
  height: 40px;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}
button:focus {
  outline: 0;
}
button:focus span {
  display: none;
}
button:focus:after {
  content: 'copied';
}
<button><span>#FF3031</span></button>
<button><span>#E84342</span></button>

Upvotes: 0

Aleksei Korkoza
Aleksei Korkoza

Reputation: 447

I think you should save your initial colours in the first state. As to the second state, you should save the selected item into it to have the latest colour and afterwards display the Copied text. If I am wrong then you should describe in detail what you expect.

import React, { useState, useCallback } from "react";

const initialColors = {
  color21: "#FF3031",
  color22: "#E84342",
  color23: "#E44236",
  color24: "#D63031",
  color25: "#EC4849",
  color26: "#E8290B",
  color27: "#E8290B",
  color28: "#AE1438",
  color29: "#FF4848",
  color30: "#FF362E"
};

const Red = () => {
  const [colors] = useState(initialColors);
  const [selectedColor, setSelectedColor] = useState({});

  const handleClick = useCallback(
    async color => {
      try {
        await navigator.clipboard.writeText(color);
        setSelectedColor(color);
      } catch (error) {
        console.log(error.message);
      }
    },
    [setSelectedColor]
  );

  return (
    <div>
      <h1 className="r-color-title">Red Color</h1>
      <div className="container-fluid">
        {Object.entries(colors).map(([id, color]) => (
          <div
            className="div-style"
            key={id}
            onClick={() => handleClick(color)}
          >
            {selectedColor.color === color ? "Copied" : color}
          </div>
        ))}
      </div>
    </div>
  );
};

export default Red;

Let's me explain one thing. I used the async/await syntax in the code because the navigator.clipboard.writeText method returns the Promise. You can read about using it in the documentation. Link: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText

Upvotes: 0

Sachin Singh
Sachin Singh

Reputation: 948

You can use useState hook to maintain the color text state for each entry. Then change the state to update the text.

import React from 'react';

const defaultColors = {
        color21 : '#FF3031',
        color22 : '#E84342',
        color23 : '#E44236',
        color24 : '#D63031',
        color25 : '#EC4849',
        color26 : '#E8290B',
        color27 : '#E8290B',
        color28 : '#AE1438',
        color29 : '#FF4848',
        color30 : '#FF362E', 
    };

const Red = () => {

    const [colors, setColorState] = useState(defaultColors);

    return (
        <div>
            <h1 className='r-color-title'>Red Color</h1>
            <div className='container-fluid'>
                {Object.entries(colors).map(([id, color]) => 
                    <div className='div-style' id={id} onClick={()=> {
                      // Copy
                      navigator.clipboard.writeText(color);
                      // Create new colors state
                      const newColorState = {...defaultColors, [id]: 'Copied'};
                      // Update the state
                      setColorState(newColorState);
                      ///
                    }}>{color}</div>
                )}
            </div>   
        </div>
    )
}

export default Red;

I hope this should work.

Upvotes: 1

Related Questions