Customize dropdown item colors in React using a color picker

I am currently utilizing a react color picker to create a personalized 16 color gradient. The process involves selecting a color from a dropdown menu and then using the color picker to make adjustments. This action updates an array that dictates the styling of each box in the dropdown. Ultimately, my objective is to modify the background of each entry in the dropdown to reflect the respective color in the gradient.

const gradientColors = ['#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000', '#000000'];

function ChangeCustomGradientColor(eventKey, color) {
gradientColors[eventKey] = color;
}

function App() {
const [color, setColor] = useState('#fff')
const [showColorPicker, setShowColorPicker] = useState(false)
const [eKey, setEventKey] = useState('');
const eventKeySelect=(e)=>{
setEventKey(e)
setShowColorPicker(showColorPicker => !showColorPicker)
}

return (
<div className="App" id="top">
<header className="App-header" id="mid">
<Dropdown onSelect={eventKeySelect}>
<Dropdown.Toggle variant="success" id="custom-color-change">
Change Custom Gradient Color
</Dropdown.Toggle>

<Dropdown.Menu >
<Dropdown.Item id="cust0" eventKey="0" style={{backgroundColor:gradientColors[0]}}>1</Dropdown.Item>
<Dropdown.Item id="cust1" eventKey="1" style={{backgroundColor:gradientColors[1]}}>2</Dropdown.Item>
...
...
...
<Dropdown.Item id="cust15" eventKey="15" style={{backgroundColor:gradientColors[15]}}>16</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
{
showColorPicker && (
<ChromePicker
disableAlpha={true}
color={color}
onChangeComplete={updatedColor => ChangeCustomGradientColor(eKey, updatedColor)}
/>
)}
</header>
</div>
)
}

In addition to the above approach, I have attempted to utilize the getElementByID method in my ChangeCustomGradientColor function, as shown below:

function ChangeCustomGradientColor(eventKey, color) {
let elementID = "cust" + eventKey;
document.getElementByID(elementID).style.backgroundColor = color;
}

While I have made progress through trial and error, I have reached a point where I recognize the importance of dedicating time to thorough JavaScript education. Any guidance or assistance would be greatly appreciated.

Answer №1

Your Dropdown.Item components are going stale because the gradientColors are being mutated by reference instead of state. The solution is to bring gradientColors into state using useState. Check out this codesandbox example for reference.

Instead of mutating directly, you should update state like this:

  initialGradientColors[eventKey] = color.hex;

By updating state in this way, you ensure that the appropriate re-renders are triggered.

  const [gradientColors, setGradientColors] = useState(initialGradientColors);
  // in some callback 
  setGradientColors(prevGradientColors => {
    const updated = prevGradientColors.map((color, index) => {
      if (index === eventKey){
        return newColor;
      }
      return color;
    })
    return updated;
  })

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

reveal concealed section and seamlessly glide to specified location inside the secret compartment

I have implemented a feature on my website where hidden divs are revealed one at a time, with the screen scrolling to display each specific div. While this code functions well, I am now looking to enhance it by opening the hidden div and smoothly scrolling ...

An error is encountered with the getToken function in the Edge Runtime when using dynamic code evaluation methods such as 'eval', 'new Function', or 'WebAssembly.compile'

Working on a project that utilizes NextAuth.JS for authentication and Redux-Saga as the state manager. To enable refresh token rotation, I have created the following set of functions: get-token.ts: import { UUID } from 'crypto'; import jwt from ...

Setting the z-index for Bootstrap dropdown menus on containers that are generated dynamically

When using the Bootstrap 3 dropdown-menu within a dynamically generated container, I am encountering an issue where the dropdown-menu appears behind the newly created elements. Please refer to the image for visual clarification. The container item has pos ...

Tips for ensuring consistent dimensions on a bootstrap card

Currently, I am working on a project to gain a better understanding of API calls within Angular. While the functionality is running smoothly, my struggle lies in designing the HTML layout. To enhance the aesthetics, I have incorporated Bootstrap 5 into the ...

The issue with Firebase's real-time database is that data constantly gets overwritten within a single node

Having an issue with writing data to my Firebase realtime database. Below is the code I am using: firebase.database().ref("ac/0/").set(null); firebase.database().ref("ac/0/").once('value', function(snapshot){ for(var i=0; ...

How can one identify a concealed glitch that exclusively occurs for a particular individual or hardware in a React environment?

Is it possible to identify a bug that occurs only with a particular individual or hardware in a React application? This bug is invisible and never appears during tests, but only manifests with a specific client within my company. Do you have any tips on h ...

Guide on utilizing ajax to post data when the URL parameter changes, all without refreshing the page

As the URL parameter changes, the values in my HTML also change. I am passing these values to a JSON file, but they are getting erased when the page refreshes due to the post request. I have attempted to use event.preventDefault(), however, it seems to n ...

Where should uploaded files be stored using ng-flow?

Initially, I am utilizing the ng-flow, which is an html5 file upload extension built on the angular.js framework. After uploading my files and logging the event in the console, I'm uncertain about where and how to store them. Below is my HTML code w ...

I noticed that the node_modules folder has mysteriously vanished from my

When I tried running npm install in the terminal of VS Code. PS D:\work\backEnd> npm install npm WARN old lockfile npm WARN old lockfile The package-lock.json file was created with an older version of npm, npm WARN old lockfile so ...

Concatenating strings with JavaScript

I am currently working on building a web page using a combination of html and javascript. I have a json file that provides inputs for some specific content I need to display. My main goal is to set up an address variable in order to show the Google Maps AP ...

The React JS @material-ui/core Select component encountered an error when attempting to access a property that does not exist: 'offsetWidth'

Struggling with the Select component from @material-ui/core, encountering the error below: Cannot read property 'offsetWidth' of null Any assistance would be greatly appreciated. Link: codesandbox Code: import React from "react"; import { ...

Minimizing conditional statements in my JavaScript code

I've just completed the development of a slider and am currently working on optimizing some repetitive if/else statements in the code. The purpose of these conditions is to determine whether the slider has reached the last slide, in which case the nex ...

Using Node.js to Send Parameters in a POST Request

I have a node.js application with an express framework and a POST route defined as follows: app.post('/test', function(req, res){ //res.send(req.body.title + req.body.body) console.log(req.params); console.log(req.body); console.log(req.bod ...

Prevent one individual cell in a table from dictating the overall table width

A B A B A X A B In a contained block with a fixed width of 400px, there is a table. When the browser width drops below 421px, the width of the containing block changes to 95%. The cells labeled "A" and "B" contain simple text. There is one cel ...

The video header on my webpage refuses to start playing upon loading

I have a video displayed in the header of my website, but it only starts playing once the user clicks on the home link in the menu to navigate to /index.html. It does not play automatically when the page first loads. I have also tried manually entering /in ...

Creating a dynamic text field integrated with Google Places in Ionic 4: a step-by-step guide

I am currently implementing the google-place-api autoComplete feature in my project, but I encountered an error: TypeError: Cannot read property 'getInputElement' of undefined .html <section [formGroupName]="i" *ngFor="l ...

Can Vue.js 3 composition be leveraged with v-for to incorporate a query string into a router-link?

I have successfully implemented v-for for a URL path. Now, I am looking to merge the URL path with the query string in the router link tag. The query string will be the date from each item rendered by v-for. Is there a way to dynamically pass this query ...

An error of type TypeError has been encountered due to an invalid argument type. This occurred in the file located at {mypath}Desktop eddit ode_modules@redisclientdistlibclientRESP2encoder.js on line

Currently, I am diving into Ben's TypeScript GraphQL Redis tutorial for the first time. As a newcomer to TypeScript, I decided to give Redis a shot. However, when I added the property req.session.userId= user.id;, things took a turn. An error popped ...

How can I incorporate random variables and functions into an if-else function when using Jquery to make #divId droppable?

I have most of my code working as I want it to, except for some basic CSS adjustments that need to be made. In a specific part of my code where I am using $("#divId").droppable({over: function(), I want to add 2 other functions and have one of them execute ...

Reacting to a click event to display a new image

I'm looking to create a webpage with multiple images where clicking on one image will open another image with its description. The images are stored locally in my library. I tried using the href attribute in the html tag, but it doesn't accept lo ...