So I have a DropDown component that I need to refactor to use GoChevronDown
and GoChevronLeft
depending upon the user clicking the Select label, I have tried this on my own and I continue to just get a blank screen:
import { useState } from "react";
import { GoChevronDown } from "react-icons/go";
function Dropdown({ options, value, onChange }) {
const [isOpen, setIsOpen] = useState(false);
const handleClick = () => {
setIsOpen(!isOpen);
};
const handleOptionClick = (option) => {
// CLOSE DROPDOWN
setIsOpen(false);
// WHAT OPTION DID THE USER CLICK ON??
onChange(option);
};
const renderedOptions = options.map((option) => {
return (
<div
className='hover:g-sky-100 rounded cursor-pointer p-1'
onClick={() => handleOptionClick(option)}
key={option.value}
>
{option.label}
</div>
);
});
return (
<div className='w-48 relative'>
<div
className='flex justify-between items-center cursor-pointer border rounded p-2 shadow bg-white w-full'
onClick={handleClick}
>
{value?.label || "Select..."} <GoChevronDown className='text-3xl' />
</div>
{isOpen && (
<div className='absolute top-full border rounded p-3 shadow bg-white w-full'>
{renderedOptions}
</div>
)}
</div>
);
}
export default Dropdown;
I thought I would add an index
to the mapping function and then compare that index to isOpen
.
I also developed an icon variable where I placed some span tags with both chevron icons.
I figured I had to put some of the elements in the second return statement inside the mapping function, but no matter how I do it I just get a blank screen.
So I have a minimal reproducible example here of what I attempted:
https://codesandbox.io/s/trusting-wind-f6dkd5?file=/src/components/Dropdown.js
But you will see that it does not look right.
There should be a Select… with an icon to the right and when you click on it some items dropdown, "red", "green", "blue" to be exact.
2
Answers
This is what I was going for, its a struggle for me writing JS in JSX sometimes, but here it is:
With this refactor, the
Dropdown
component will display theGoChevronDown
icon when the dropdown is clicked and theGoChevronLeft
icon when the dropdown is not clicked. This is what I was going for, but it was a struggle to figure it out, again writing JS in JSX can be sometimes painful for me. My apologies for any confusion.Since you’re already holding the selected item in a useState in
<App>
, you could use that value to check if the icon should be opened or closed.Since
option.value
hold the current option from the iteration, andvalue.value
will hold the selected value, no need to keep track of the ‘selected index’Regarding OP’s comment, if you want the
icon
to only show it with the ‘select’, you can move it next to the select using a fragment and an if/else that will choose betweenvalue.label
orSelect + icon
Small demo from your fiddle
With some minor changes to make it work here in a SO snippet