Задать вопрос
@QnaTwitt

Как переписать код компонента select?

Подскажите как переписать компонент select, что бы он работал не зависимо, если их несколько на странице

Код компонента:
import { FC, useState, useEffect, useRef } from "react";
import { className } from "../../../app/client/helper.client";

interface IOption {
  id: number | string;
  render: () => any;
}

interface ISelect {
  optionsList: IOption[];
  defaultValue: IOption;
  getSelectedValue: any;
  absolute?: boolean;
}

const Select: FC<ISelect> = ({
  optionsList,
  defaultValue,
  getSelectedValue,
  absolute
}) => {
  const selectRef = useRef(null);
  const optionsRef = useRef(null);
  const [height, setHeight] = useState('0px');
  const [isOpen, setIsOpen] = useState(false);
  const [defaultSelectValue, setDefaultSelectValue] = useState(defaultValue);

  useEffect(() => {
    document.addEventListener("mousedown", handleClickOutside);

    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, [defaultValue]);

  const handleClickOutside = (event) => {
    const path = event.path || (event.composedPath && event.composedPath());

    if (!path.includes(selectRef.current)) {
      setIsOpen(false);
    }
  };

  useEffect(() => {
    setHeight(isOpen ? '0px' : `${optionsRef.current.scrollHeight}px`);
  }, [isOpen]);

  const handleListDisplay = () => {
    setIsOpen(!isOpen);
  };

  const handleOptionClick = (selectedValue) => {
    setIsOpen(!isOpen);
    setDefaultSelectValue(selectedValue);
    getSelectedValue(selectedValue);
  };

  return (
    <div
      className={`select ${absolute ? '--absolute' : ''}`}
      ref={selectRef}
    >
      <span
        className={isOpen ?  '--open' : ''}
        onClick={handleListDisplay}
      >
        {defaultSelectValue.render()}
      </span>
      <ul ref={optionsRef} style={{ height: height }}>
        {optionsList.map((option) => (
          <li
            key={option.id}
            onClick={() => handleOptionClick(option)}
          >
            {option.render()}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Select;


Стили:
.select {
  &.--absolute {
    position: relative;

    ul {
      position: absolute;
    }
  }

  ul {
    overflow: auto;
    transition: height .3s ease-in-out;
  }
}


Вызов
const selectOptions = [
    { id: "1", render: () => (<div>1111</div>) },
    { id: "2", render: () => (<div>2222</div>) }
  ];

<Select
  optionsList={selectOptions}
  defaultValue={selectOptions[0]}
  getSelectedValue={(e) => console.log(e)}
/>
  • Вопрос задан
  • 53 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Faershtein
используй библиотеку downshift https://www.downshift-js.com/downshift ,
тоже мучались в проекте над этой проблемой, в итоге выбрали эту либу, отлично справилась
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы