Skip to content
This repository has been archived by the owner on Sep 10, 2022. It is now read-only.

Why recommend Hooks API? #756

Open
brodycj opened this issue Oct 28, 2018 · 24 comments
Open

Why recommend Hooks API? #756

brodycj opened this issue Oct 28, 2018 · 24 comments

Comments

@brodycj
Copy link

brodycj commented Oct 28, 2018

Considering that this library has already solved the problem of using state, without needing classes, and without the gotchas described in https://reactjs.org/docs/hooks-rules.html, I was wondering why you guys would recommend the new Hooks API. Any comments would be much appreciated.


UPDATE March 2021: some new updates are available in react-recompose.

@rjhilgefort
Copy link

After seeing the blurb at the top of the README I came to the issues to start a discussion on this as well.

The idea and architecture of creating an ecosystem of Higher Order Components (HoC) that "do one thing well" is still valid and, in my eyes, easier to reason about than hooks. Don't get me wrong, I love hooks and the encapsulation they promote. I also agree with the statement that react-hooks can solve all the same problems, but they rely on injecting the hooks inside of your component rather than wrapping a component that would otherwise have no references to the added functionality. I still see value in working with HoCs and glueing HoCs together on top of "dumb" components.

@acdlite I know working at Facebook on the React team and that probably has some influence, but please don't "deprecate" this package. Consider rewording your statement on the README that puts forth a world where both strategies can, and would be valid, to exist.

As always, thank you for all the work you did on recompose!

@michelalbers
Copy link

I just discovered this and am greatly pleased with recompose. It cleans up my code a lot. Im my case I'm just converting all the nested <Query /> components to a nice recompose flow with loading and error branches. Will the new react hooks really be a complete replacement?

@DWMiller
Copy link

DWMiller commented Oct 30, 2018

For simple things like withState the answer seems almost obvious. Basically the same amount of code, but with no composition, no dependencies, no nesting in the component tree, just a bit of react and it works.

I certainly can't speak for all use cases of recompose, but if I can get the same functionality alongside those gains, I'm all for it.

@hk-ng
Copy link

hk-ng commented Oct 31, 2018

I think we should leave example of the hook API with on each existing recompose API.
Like withhandlers, mapProp

@michelalbers
Copy link

Just watched Sophie's and Dan's talk and I can see why @acdlite thinks this way. It is too early to call this library deprecated or obsolete IMHO. I like @hk-ng's idea - lets do it!

@Wollantine
Copy link

Wollantine commented Nov 3, 2018

@DWMiller IMHO, losing the ability to compose functions, or components, is not a gain.

Components should be pure functions (idempotent && deterministic) in order to be properly tested. Imagine a big store with a deep structure like {a: {b: {c: {d: {e: true}}}}}. You can abstract the connecting logic like this:

const eReusableSelector = ({a}) => ({e: a.b.c.d.e})

compose(
     getContext(MyComplexStore),
     mapProps(eReusableSelector),
)(MyComponent)

And still be able to test MyComponent because it simply takes an e prop.
With Hooks, you have to couple the selector logic to the component or to the Hook, thus needing to mock the store in the tests:

const mockedStore = {a: {b: {c: {d: {e: true}}}}}
const myWrapper = render(<Provider value={mockedStore}><MyComponent></Provider>)
// Instead of
const myWrapper = render(<MyComponent e={true}/>)

Or you can do a HOC that only contains the Hook. That is composable. Wonder if anyone would do a library for that... Oh wait, that's what Recompose is!

Another example would be composability in general: Recompose gives us some amazing HOCs that allow things like renderNothing, renameProps, or branch, that I don't see React's Hooks have any way to approach at all.

So, the conclusion for me is that Recompose solves all the problems they attempted to address with Hooks, and more on top of that, not the other way around.

@rjhilgefort
Copy link

@DWMiller Well said! My thoughts exactly!

@Synvox
Copy link

Synvox commented Nov 4, 2018

I had the same thought, but I do love the fact that hooks don't require wrapping components. Why not implement a recompose-like api on top of hooks?

https://github.com/Synvox/rehook

This project is still a little new. There are probably a few bugs. I'd love to get feedback and some contributions.

@rjhilgefort
Copy link

@Synvox Love the idea and the effort on rehook! For me, the rub is still on how the dumb/presentation component has to "know" about the hook and call it in its implementation. Doing so couples the code and removes the dependencies from the interface (the props). With recompose, the dumb/presentation components don't care how the props get to them and that allows for the implementation of the props being passed down to change as needed without affecting the component that's consuming them.

@Synvox
Copy link

Synvox commented Nov 4, 2018

@rjhilgefort I agree, and that decoupling is why I use recompose too. The nice thing about rehook is you can use it to map props to a dumb component.

https://codesandbox.io/s/0vx6nn39n0?module=%2Fsrc%2FCounter.js

import React from "react";
import { pipe, withState, withHandlers } from "@synvox/rehook";

const enhance = pipe(
  withState("count", "setCount", 0),
  withHandlers({
    increment: ({ setCount, count }) => () => setCount(count + 1),
    decrement: ({ setCount, count }) => () => setCount(count - 1)
  })
);

const Counter = ({ increment, decrement, count }) => (
  <>
    <button onClick={increment}>+1</button>
    {count}
    <button onClick={decrement}>-1</button>
  </>
);

export default pipe(
  enhance,
  Counter
);

The last line there is the important one:

export default pipe(
  enhance,
  Counter
);

Like recompose, all rehook enhancers accept and return a props object. They can be composed together as a smart component fairly easily.

@hitmands
Copy link

similar topic here #759

@rjhilgefort
Copy link

@hitmands Would you mind moving your comment over to this thread and closing your issue so the conversation is collected in one place?

@hitmands
Copy link

I am all in favour with what @rjhilgefort said.

While react hooks solves most of the issues that recompose attempts to solve, the approach taken is very different between them.

  • react hooks allows enhancement by embedding business logic
  • recompose allows enhancement by function composition

recompose's approach lets you build sophisticated components by composing small building blocks together (HOCs) which can be tested separately. The final dumb component has to take care of the rendering only, which can be done in a pure and deterministic way. With recompose, a dumb component can entirely work with its arguments passed as props, making it easy to test and maintain.


Hi! I created Recompose about three years ago. About a year after that, I joined the React team. Today, we announced a proposal for Hooks. Hooks solves all the problems I attempted to address with Recompose three years ago, and more on top of that. I will be discontinuing active maintenance of this package (excluding perhaps bugfixes or patches for compatibility with future React releases), and recommending that people use Hooks instead. [...]

I don't really think that saying "Hooks solve all the problems..." is entirely correct, react hooks gives a (kind of) life cycle, as well as state and side effect management (etc...) to functional components but recompose is still very useful from the architectural standpoint.

So, please, let's all rethink over dismiss recompose.

@gaearon
Copy link

gaearon commented Nov 14, 2018

To clarify:

Andrew hasn’t been working on new features in Recompose for two years. So declaring that he doesn’t plan to add new features to it doesn’t change anything in practice for existing users.

Andrew feels uneasy about recommending Recompose for new projects when Hooks solve a large subset of the same problems without introducing excessive tree nesting and similar issues. I agree the wording was perhaps too strong but he’s the maintainer and he has the right to point out its flaws. He plans to write a longer article to explain what he meant because it seems like there’s a lot of FUD going on.

If you’re happy with Recompose and don’t experience its downsides, you can keep on using it without any issues. New versions of Recompose will continue to be released together with React updates etc.

@danielo515
Copy link

Hey, I know that I'm a bit late to the party but, here are my two cents:
why not slim down re-compose a bit and remove the functionality that hooks solves and leave the extra goods that recompose adds ?

On the other hand, is recompose compatible with other react implementations as inferno or preact ? if so, hooks does not solve anything for those users.

Regards

@icopp
Copy link

icopp commented Feb 13, 2019

I too would appreciate a 'slim recompose' that includes the stuff like setDisplayName that you can't do with hooks.

@ott-web
Copy link

ott-web commented Feb 14, 2019

Too bad React Native doesn't have Hooks support until 0.59... We're on 0.58 now. Need to write some lifecycle HOCs now and can't believe I have to write it with recompose only to rewrite it with Hooks later. Sad.

@danielkcz
Copy link

@ott-web I do not have it as a tested solution, so don't take my word for it. Considering that Hooks are mostly just additive feature, why not to install React 16.8 to your RN project even though it's not officially supported yet? With some fingers crossed, it might work 😄

@dmitryplatonov
Copy link

I believe Recompose can use hooks as implementation of it's withState and some other HOCs to give flatter hierarchy and (probably) better performance.
I can agree that functional API of recompose is better than declarative of Hooks.

@danielkcz
Copy link

(probably) better performance.

Most likely not, because of every extra component wrapping (every HOC) adds some extra overhead. If you have a single state within a HOC and pass that down through the props, it's surely slower than declaring that state directly in the component. Especially if have multiple states. I do not have any benchmarks to prove that, but it should be obvious :)

@dmitryplatonov
Copy link

I was thinking that pipe/compose can flatten/fuse some levels of HOCs into single wrapper (for built-in HOCs), so multiple withState will resuilt in single wrapper.

@jgretz
Copy link

jgretz commented Jun 13, 2019

I know I'm late to the conversation, but if continuing in a recompose style while gaining the benefits of hooks is something that appeals to you, I'd invite you to check out @truefit/bach (https://bach.truefit.io & https://github.com/truefit/bach)

It combines all of your enhancer calls into a single HOC wrapper, and uses hooks for the underlying functionality where applicable.

@augustindlt
Copy link

augustindlt commented Mar 1, 2020

I'm quite a fan of recompose and when I learned about the end of the maintenance of the project I was really interested in hooks. But I did not find a way to combine my custom hooks with my HOCS, that's why I created a library that can perhaps help you too: https://github.com/augustindlt/wizhooks

@KrisLau
Copy link

KrisLau commented Jun 1, 2022

@acdlite I might be mistaken but there's quite a few parts of recompose that hooks still doesn't solve like fromRenderProps? Would it not be ok to have this repo be maintained since it works pretty well together with Hooks and HOCs

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests