A hook enables a client to define some custom behaviour that the applicator of the hook (a component for most cases) should apply. The behaviour is often closely tied to some data provided by the client. In fact, in most cases those data is needed to configure the Effect, which is usually done in appropriate
operator fun invoke methods.
So, the client has to configure the values defined by the property portion and the applicator applies the effect within its own UI context C.
The applicator can pass additional data into the effect as payload P (think of some
`close` handler passed into the apply-expression to enable the client to create some custom close-button for example).
The applicator can easily execute the Hook by calling one of the hook methods, which basically simply pass the payload into the Effect and executes it. Finally an optional alsoExpr has to be applied to the return value R in the different variations of the Effect.
If an implementation needs some complex payload, use some dataclass or other containers to comply to its signature.
DO NOT CREATE SOME OTHER HOOK ABSTRACTION WITH MULTIPLE TYPES FOR THE PAYLOAD! (So please NO
Hook<C, R, P1, P2, ...>!!!)
For the special cases where an applicator knows about the specific internal rendering structure of a hook implementation, prefer to use TagHook or apply the special payload type TagPayload by yourself.
Components should strive to use hooks for all their parts that need to be configurable and varying in their behaviours. Think of some input-field that should render a label next to it. This label clearly needs to be configured by the calling client, so it must be configurable. The label could be reused for different kind of form control elements too, so it clearly makes sense to encapsulate the configuration and its representation (the rendering function) into one object that should be some kind of hook.