I have created multiple dropdowns and I am trying to replace the TITLE dynamically when user clicks on an dropdown option. So when user clicks on a dropdown option, the title on the top of the dropdown changes. I used useRefs on each dropdown loop through a .map() array function.
I managed to change the title values on the array and I have tried to dynamically replace a value in a looped useRef array but i cant figure out to get it working. I tried to replace it using setState hook but its giving me an error and the .map() is not working.
Any tips will be greatly appreciated! heres my what the dropdowns look like:-
Link to codepen:-
JSX: -
const [isSortButtonClicked, setIsSortButtonClicked] = useState(false);
const [buttonTitles] = useState(defaultTitles);
const [chosenTitles, setChosenTitles] = useState([]);
const [isDropdownOpen, setIsDropdownopen] = useState(false);
let buttonRef = useRef([]);
// set chosen titles ----------------------------------
const handleSort = () => {
setChosenTitles((chosenTitles) => [
...chosenTitles,
buttonTitles[0],
buttonTitles[1],
buttonTitles[2]
]);
setIsSortButtonClicked(true);
};
/* trying fix implementation for change title */
// handle change title --------------------------------
const handleChangeTitle = (index, indexOfDiv) => {
console.log("index of buttonTitles", index);
console.log("index of chosenTitle", indexOfDiv);
console.log(buttonTitles[index]);
// this is what i have so far, but it does not work
// setChosenTitles(
// (chosenTitles[index] = buttonTitles[indexOfDiv])
// );
};
// close dropdown -------------------------------------
useEffect(() => {
if (!isDropdownOpen) {
chosenTitles.forEach((_, index) => {
buttonRef.current[index].classList.remove("active");
});
}
}, [chosenTitles, isDropdownOpen]);
// open dropdown
const handleOpenDropdown = (indexOfDiv) => {
setIsDropdownopen((prev) => !prev);
buttonRef.current[indexOfDiv].classList.add("active");
};
// handle hover background change ----------------------
const [indexOfTitle, setIndexOfTitle] = useState();
const handleHoverTitle = (indexOfDiv) => {
setIndexOfTitle(indexOfDiv);
};
Return statement:-
return (
<>
{isSortButtonClicked ? (
""
) : (
<button onClick={handleSort} className="sortBtn">
Sort
</button>
)}
{chosenTitles.map((title, indexOfDiv) => {
return (
<div
key={indexOfDiv}
className="dropdown"
ref={(ref) => (buttonRef.current[indexOfDiv] = ref)}
>
<div
className="button"
onClick={() => handleOpenDropdown(indexOfDiv)}
>
{title}
{CHEVRON_DOWN}
</div>
<div className="content">
{buttonTitles.map((buttonTitle, index) => {
return (
<div
key={index}
onClick={() => handleChangeTitle(index, indexOfDiv)}
onMouseEnter={() => handleHoverTitle(index)}
style={{
background:
index === indexOfTitle && "rgba(55, 53, 47, 0.08)"
}}
>
<p>{buttonTitle}</p>
</div>
);
})}
</div>
</div>
);
})}
</>
);

