简体   繁体   中英

change background color using react color picker

I have a section in which I want users to be able to change the background color using react color picker and react-redux, unfortunately, the background color is not changing / not updating to a new color.

Live code in codesandbox: change background color

Source code:

  import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { ChromePicker } from "react-color";
import Details from "./Details";

const Settings = () => {
  const fields = useSelector((state) => state);
  const dispatch = useDispatch();
  const [colorRgb, setColorRgb] = useState("#000");

  useEffect(() => {
    updateColor();
  }, []);

  const updateColor = () => {
    dispatch({
      type: "change",
      name: "socialColor",
      value: colorRgb
    });
  };
  console.log("current color", colorRgb);
  console.log("current color", fields.color);
  return (
    <div>
      <div>
        <Details />
        <h1>Edit </h1>
        <div className="container">
          <ChromePicker
            renderers={false}
            color={colorRgb}
            onChange={(e) => setColorRgb(e.hex)}
          />
          <span
            className="testa"
            style={{
              background: fields.color,
              color: "#fff"
            }}
          >
            Change my background color
          </span>
        </div>
      </div>
    </div>
  );
};

export default Settings;

What is wrong with my code.?

You just need to set background in syntax of rgba(r, g, b, a) instead of {r, g, b, a} which is invalid css

import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { ChromePicker } from "react-color";

const Settings = () => {
  const fields = useSelector((state) => state);
  const dispatch = useDispatch();
  const [colorRgb, setColorRgb] = useState(fields.color);

  useEffect(() => {
    updateColor();
  }, []);

  const updateColor = () => {
    dispatch({
      type: "change",
      name: "socialColor",
      value: colorRgb
    });
  };
  console.log("current color", colorRgb);
  return (
    <div>
      <div>
        <h1>Edit </h1>
        <div className="container">
          <ChromePicker
            renderers={false}
            color={colorRgb}
            onChange={(e) => setColorRgb(e.rgb)}
          />
          <span
            className="testa"
            style={{
              background:
                "rgba(" +
                colorRgb.r +
                "," +
                colorRgb.g +
                "," +
                colorRgb.b +
                "," +
                colorRgb.a +
                ")",
              color: "#fff"
            }}
          >
            Change my background color
          </span>
        </div>
      </div>
    </div>
  );
};

export default Settings;

You are only calling the updateColor function which calls dispatch one time when the component mounts. This doesn't make any sense because your redux value will always be black.

If you want to store "pending" changes in the component then you would use a local component state and call dispatch when clicking a "Submit" button.

Probably you want to call dispatch on every change and get rid of the local useState .

@ibra is correct about needing to format the color object into a string but you can write it more concisely.

It's up to you whether you want to convert from an object to a string before you store it in redux or after you retrieve it.

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { ChromePicker } from "react-color";
import Details from "./Details";

export const rgbaString = ({r, g, b, a = 1}) => `rgba(${r},${g},${b},${a})`

const Settings = () => {
  const colorRgb = useSelector((state) => state.color);
  const dispatch = useDispatch();

  const onChangeColor = (e) => {
    dispatch({
      type: "change",
      name: "color",
      value: e.rgb
    });
  };
  
  return (
    <div>
      <div>
        <Details />
        <h1>Edit </h1>
        <div className="container">
          <ChromePicker
            renderers={false}
            color={colorRgb}
            onChange={onChangeColor}
          />
          <span
            className="testa"
            style={{
              background: rgbaString(colorRgb),
              color: "#fff"
            }}
          >
            Change my background color
          </span>
        </div>
      </div>
    </div>
  );
};

export default Settings;

The problem will be fixed if you get the hex code instead of rgb

your code

   <ChromePicker
     renderers={false}
     color={colorRgb}
     onChange={(e) => colorChange(e.rgb)}
   />

must be

   <ChromePicker
     renderers={false}
     color={colorRgb}
     onChange={(e) => colorChange(e.hex)}
   />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM