3 ms·
> You basically stick to writing pure functional components focused only on how to render If you’re using hooks like useState or useEffect I wouldn’t consider
by enumjorge 5y ago
> You basically stick to writing pure functional components focused only on how to render
If you’re using hooks like useState or useEffect I wouldn’t consider those functional components pure.
Hooks provide some nice syntactic sugar, which is not nothing, and make it easier to share logic between components. In my experience hooks have made my code easier to read, but they haven’t simplified it. The side effects and state might not be inlined but they’re still there. If anything they’ve made it less explicit because some of the details are hidden behind the magic that the React runtime uses to add state to functions.
- bern4444 5y agoI’m sure the parent author knows this But the beauty of hooks is as you say reusable statefull behavior. It also lets you treat your functional components more like a pure function in my opinion. If the hooks you use are poorly designed, then yeah, it may be more difficult. But well designed and implemented hooks make your component appear more like a pure function. The state is (more) decoupled from the UI code than before and lets me easily reuse behaviors across components.
- nexuist 5y agoThey're technically not pure, but they're as close as we can get to functional-style state handling: declare dependencies upfront so the caller knows exactly what they'll get when they execute your function. Fully state-less code achieves basically nothing; you need to "escape the hatch" eventually to work with the rest of the architecture. Hooks are very beautiful escape hatches that let you deal with persistence without having to sacrifice the rest of your function's body to it.
- bern4444 5y agoReally well said. And if you really wanted to make it 'pure', you could easily write a hook with an explicit return type that wraps the type of the initial value. If you're using typescript, you can then limit the possible types of the generic to only monads. type State<T> = val as T; const useStatex = <T>(initialState: T) => { const [state, setState] = useState(initialState); return [state, updateState] as [State<T>, (val: T) => void]; } This new hook, useStatex, has an explicit type definition that indicates something stateful is taking place. Same as Futures. You can take this even further in the typing limiting the generic to only allow certain types for the underlying values to be monads, or even more simply type State<T> = Promise<T> | Array<T> | Option<T> So you avoid an extra layer of nesting like State<Future<Array<T>>> Point is, there are lots of ways to easily resolve any its not pure! arguments same as any other functional programming concept eta The simplest way to limit the return type might even be to just do this const useStatex = <T extends Promise | Array | Option>(initialState: T) => {