Search code examples
reactjsevent-handlingmaterial-uidom-eventsreact-props

Event Handling - React


I have a popover inside which there are Colors components with different colors. Also there is a icon DoneIcon which (for time being) is placed inside the Colors component. What I'm trying to achieve is:

  1. After hovering when I select a color(with no icon inside), DoneIcon should be placed inside it. To generalize when a color is selected it should have DoneIcon and the icon should disappear from the previously selected color.
  2. When the color is selected the background color of (its parent) div with class="box" should change to the selected color. I know this can be achieved with event handling by having functions for each color(out of 12 colors) which will be executed onClick, but how can I have only one function which will detect the color from props.color when onClick event executes and apply the color to box.

Here is the link for CodeSandbox


Solution

  • Add a selected prop to your Colors component

    function Colors(props) {
      return (
        <div
          onClick={props.setColor(props.color)}
          className="colors"
          style={{ backgroundColor: props.color }}
        >
          {props.selected && <DoneIcon fontSize="small" />}
        </div>
      );
    }
    

    In your parent:

    const [color, setColor] = useState("");
    ...
    
    <Colors selected={color === "red"} setColor={setColor} color="red" />
    

    Note: you'll probably want to refactor this solution, but something like this should work.

    Thoughts on refactoring

    Map over a list of colors

    const [selectedColor, setSelectedColor] = useState('')
    
    ['red', 'blue', 'green'].map(color => {
      <div onClick={() => setSelectedColor(color)} className="colors" style={{ backgroundColor: color }}>
        {selectedColor === color && <DoneIcon fontSize="small" />}
      </div>
    }
    

    Working: codesandbox

    Refactored to use Colors component: codesandbox