I am trying to add an edit button (which currently triggers an alert) to my react-select component. However, this makes the newly added button unclickable; instead, it opens the react-select menu. Stopping propagation does not solve the issue.
const CustomOption = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This is working like I want");
};
return (
<components.Option {...props}>
<div className="test">
<span>{props.children}</span>
<button onClick={handleEdit}>Edit</button>
</div>
</components.Option>
);
};
export default function App() {
const option = [
{ value: "Spring", label: "Spring" },
{ value: "Summer", label: "Summer" },
{ value: "Autumn", label: "Autumn" },
{ value: "Winter", label: "Winter" },
];
return (
<div className="App">
<Select
className="dropdown"
options={option}
components={{ SingleValue: CustomSingleValue }}
/>
</div>
);
}
Question: Why doesn’t the button inside CustomSingleValue work (while the one inside CustomOption does), and how can I fix it?
This is especially frustrating because CustomOption, which uses the exact same code, works fine.
Full code including working CustomOption:
// This isn't working like I want
const CustomSingleValue = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This I can't click");
};
return (
<components.SingleValue {...props}>
<div className="test">
<span>{props.children}</span>
<div>
<button onClick={handleEdit}>Edit</button>
</div>
</div>
</components.SingleValue>
);
};
// This is working how I want
const CustomOption = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This is working like I want");
};
return (
<components.Option {...props}>
<div className="test">
<span>{props.children}</span>
<button onClick={handleEdit}>Edit</button>
</div>
</components.Option>
);
};
export default function App() {
const option = [
{ value: "Spring", label: "Spring" },
{ value: "Summer", label: "Summer" },
{ value: "Autumn", label: "Autumn" },
{ value: "Winter", label: "Winter" },
];
return (
<div className="App">
<Select
className="dropdown"
options={option}
placeholder="Click on a option and then try to click the edit button"
components={{ SingleValue: CustomSingleValue, Option: CustomOption }}
/>
</div>
);
}
3
Answers
enter image description here
just add position: relative on the option container, it will work
you see when an option is selected and is being shown in the input, it is a layer underneath the input, thus, despite the fact that you are seeing the option there, when you click on it, you are not actually clicking on that, you are clicking on the select input causing the options dropdown to open.
Issue number one: you have a react-select input overlayed your component, hence you click it instead of your single value component:
To address that, you need to add
z-index
:After that, the button works well, however, we still get the dropdown opened. That’s because react-select uses
onMouseDown
rather thatonClick
. The easiest way to fix it is to useonMouseDown
too:If you want to keep
onClick
, just add another handler foronMouseDown
that only stops propagation.