Overview
React Hooks are powerful
but, there's room for improvement!
Faulty Abstraction
Conceptually, once a hook is defined on a component, it is static and cannot be added/removed and cannot change positions. React relies on linters and the rules of hooks to prevent people from making these mistakes, but the better solution is to declare hooks during the construction of a component as opposed to during the render. If we only allow hooks to be declared on construction, we eliminate the need for linters and rules because the component will never attempt to re-declare them during the render phase.
Tight Coupling
Hooks are awesome because they've allowed the community to abstract common needs into libraries. Take for example react-query, which has imensely simplified the way we handle async state in React apps. However, wouldn't it be great if react-query could be used with other UI frameworks like vue, svelte, or even without a framework? Elementos aims to make this possible by pulling state/effect responsibilities out of React and putting them in to a separate package.
Web Consistency
Functional reactive programming has been around for a long time, but in recent years many UI frameworks have embraced it including ember, angular, vue, and svelte. React is pseudo-reactive but hasn't embraced FRP to the extent that other frameworks have and in this way has diverged from the rest of the modern web. Elementos hopes to re-align the React community with other modern web communities.
Inefficient
React encourages us to put our business logic in the render function of our components, but this leads to unneccesary recomputation of values. We have the option to bail out of these recomputations via useMemo
and useCallback
, but the better solution is to run business logic only as much as necessary, which elementos encourages us to do via derived observables.
React with elementos
Installation
Here's a quick look at how we can use React and elementos together. If you're looking for a more in-depth example, please see the notes app built with React and elementos.
Local State
Local state is everywhere in React apps and it's pretty simple with elementos as well. We can initialize and return atoms in a constructor function and then use the useObservable
hook to translate the observables to react state.
Effects
To achieve effects with elementos, we can set up observers in the constructor function to monitor observables and run effects whenever their values change. Note that the observe
function returns a disposer which we schedule to run when the component unmounts.
Disposing Observers
We should take care to dispose of any observers before the component unmounts. The constructor takes a beforeUnmount
argument that let's use queue disposal functions.
Refs
Who needs refs when you've got atoms? Because refs are essentially just state that doesn't cause a component to re-rerender, atoms are a natural substitute for refs with the added benefit that they're observable.
Global State
Global state is easy as well. All we have to do is define our observables outside of our components and then we can use them inside of components to share state across.