skip to Main Content

I am trying to lean react by solving a problem in react. Providing the react code challenge below.
I am trying to close the drop down when I click outside. I tried to debug but no luck.
Can you guys give comments for the code toolbar, its hard to understand the video for each functionality.
I googled spread, use ref but not sure why he is using spread too

I googled but still no luck, not sure how to solve it. Providing my code below and stackblitz. Can you guys help me.

https://www.youtube.com/watch?v=V2zEAXLQbF4&list=PL6x5Q-Sj_Bla3_wMqhETxMBjFml0XJNPI&index=11

https://stackblitz.com/edit/stackblitz-starters-ngl4yu?description=React%20%20%20TypeScript%20starter%20project&file=src%2Fcomponents%2FstateDropdown.css,src%2Fcomponents%2FStateDropdown.tsx,src%2FApp.tsx,src%2Fcomponents%2FStates.tsx&title=React%20Starter

import { useEffect, useRef, useState } from 'react';
import './stateDropdown.css';
import { states } from './States';
export function StateDropdown() {
  const [isDropDownDisplayed, setIsDropdowndisplayed] = useState(false);
  const [selectedStates, setSelectedStates] = useState<Record<string, boolean>>(
    states.reduce((obj, state) => ({ ...obj, [state.abbreviation]: false }), {})
  );
  const numberOfStatesSelected =
    Object.values(selectedStates).filter(Boolean).length;
  const dropDownRef = useRef(null);
  useEffect(() => {
    const onClick = (e: any) => {
      if (e.target !== dropDownRef.current) {
        console.log('we are here');
        setIsDropdowndisplayed(false);
      }
    };
    document.addEventListener('click', () => {});
    // clean up
    return () => {
      document.removeEventListener('click', onClick);
    };
  }, []);
  return (
    <fieldset className="state-dropdown">
      <button
        className=""
        onClick={(e) => {
          e.stopPropagation();
          setIsDropdowndisplayed((prevState) => !prevState);
        }}
      >
        {numberOfStatesSelected > 0
          ? `${numberOfStatesSelected} states selected`
          : '-- Select your states --'}

        <svg
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
          stroke-width="1.5"
          stroke="currentColor"
          className="w-6 h-6"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5"
          />
        </svg>
      </button>
      {isDropDownDisplayed && (
        <div
          onClick={(e) => {
            e.stopPropagation();
          }}
          ref={dropDownRef}
          className="panel"
        >
          {states.map((state) => (
            <fieldset
              key={state.abbreviation}
              className={selectedStates[state.abbreviation] ? `selected` : ''}
            >
              <input
                onChange={(e) =>
                  setSelectedStates({
                    ...selectedStates,
                    [state.abbreviation]: e.target.checked,
                  })
                }
                checked={selectedStates[state.abbreviation]}
                id={`input-${state.abbreviation}`}
                type="checkbox"
              />
              <label htmlFor={`input-${state.abbreviation}`}>
                {state.name}
              </label>
            </fieldset>
          ))}
        </div>
      )}
    </fieldset>
  );
}

2

Answers


  1. To make the menu close if you click outside of the menu you just need to update
    document.addEventListener('click', () => {});

    to

    document.addEventListener('click', onClick);

    Currently you are creating an event listener that is not doing anything but we need it to trigger your onClick to check if the click was within the menu or not.

    Login or Signup to reply.
  2. you can use antd dropdown
    see here

    or you can add an onclick function to the container of the dropdown

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search