Full reproduction: codesandbox link .
I am trying to create a custom search/select component with react. My problem lies in execution order of events.
When a user focuses in on the text input field, a list with options should be shown. Then when the user clicks on one of the items in the dropdown, the element name should be filled in the text input field and then the list should be hidden.
I achive this by creating a inputFocused
boolean state, and rendering list only when inputFocused
is true. I attach twop event handlers on the text input itself:
-
onFocus={() => setInputFocused(true)}
-
onBlur={() => setInputFocused(false)}
But when a user clicks on one of the items, input is not getting filled.
<input
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value);
}}
onBlur={() => setInputFocused(false)}
onFocus={() => setInputFocused(true)}
/>
{inputFocused && (
<ul>
<li onClick={() => setSearchTerm(element.name)}>{element.name}</li>
</ul>
}
Check codesanbox link for better understanding.
I think i understand the problem. onBlur()
event triggers before the onClick()
event. If i wrap the onBlur callback function inside a setTimout, it will work as expected:
onBlur={() =>
setTimeout(() => {
setInputFocused(false);
}, 100)
}
I would like to avoid defining a setTimeout.
Is there solution to make sure that onClick()
on <li>
executes before onBlur()
on <input />
?