The way I like to put it is that stateless components are great because they don't have a mind of their own. Stateless components have one responsibility, and that is to encapsulate all of the UI details of a component, but not the functionality of that component.
The dropdown component is a great example actually. It is a minor convenience for the dropdown component to have it's own "open/closed" state. However, when you need more explicit control over the dropdown in a certain portion of the interface (i.e. this dropdown should open not only when I click on it's trigger element, but also when I enter the konami code on some other portion of the site) then it becomes a less minor inconvenience that the open/closed state is actually not in your control.
In general, I do create stateful wrapper components for things like this. A single stateless component that handles common UI details can be wrapped by multiple stateful components that handle functionality. Here's a simplified dropdown/tooltip example.
HoverCard component: A stateless "floating div" component that can be styled and positioned around a trigger element. Handle things such as listening for events (Esc pressed, click or hover over the trigger, detect clicks outside of the HoverCard) and fitting the HoverCard onto the screen if there is some overflow.
Dropdown component: A stateful wrapper component around the HoverCard component with custom functionality. Manages it's own "open/closed" state which is toggled via the event callbacks (onEsc, onClickTriggerEl, onClickOutsideHoverCard) it supplies to HoverCard.
Tooltip component: Another stateful wrapper component around HoverCard which is very similar to Dropdown but with different HoverCard styling and slightly different "open" state management. For example, it uses the onMouseOverTriggerEl and onMouseLeaveTriggerEl HoverCard callbacks instead of the onClickTriggerEl HoverCard callbacks to toggle its open state.
The cool thing is that they both get all of the benefits of HoverCard.
The dropdown component is a great example actually. It is a minor convenience for the dropdown component to have it's own "open/closed" state. However, when you need more explicit control over the dropdown in a certain portion of the interface (i.e. this dropdown should open not only when I click on it's trigger element, but also when I enter the konami code on some other portion of the site) then it becomes a less minor inconvenience that the open/closed state is actually not in your control.
In general, I do create stateful wrapper components for things like this. A single stateless component that handles common UI details can be wrapped by multiple stateful components that handle functionality. Here's a simplified dropdown/tooltip example.
HoverCard component: A stateless "floating div" component that can be styled and positioned around a trigger element. Handle things such as listening for events (Esc pressed, click or hover over the trigger, detect clicks outside of the HoverCard) and fitting the HoverCard onto the screen if there is some overflow.
Dropdown component: A stateful wrapper component around the HoverCard component with custom functionality. Manages it's own "open/closed" state which is toggled via the event callbacks (onEsc, onClickTriggerEl, onClickOutsideHoverCard) it supplies to HoverCard.
Tooltip component: Another stateful wrapper component around HoverCard which is very similar to Dropdown but with different HoverCard styling and slightly different "open" state management. For example, it uses the onMouseOverTriggerEl and onMouseLeaveTriggerEl HoverCard callbacks instead of the onClickTriggerEl HoverCard callbacks to toggle its open state.
The cool thing is that they both get all of the benefits of HoverCard.