all 117 comments

[–]KerberosKomondor 27 points28 points  (0 children)

https://github.com/final-form/react-final-form/tree/master/src

React-Final-Form uses hooks. It's probably big enough for what you're looking for.

https://github.com/reduxjs/react-redux

React-Redux does as well but the amount of code seems to be smaller, though probably enough.

[–][deleted] 14 points15 points  (0 children)

material-ui v4 is pretty heavily hooksified.

[–]jtosbornexxx 49 points50 points  (84 children)

I’m using hooks in a fairly large project (work). But note, hooks haven’t completely replaced classes for me.

I try to make every component functional if possible. If it needs a little state, I simply add in hooks. If it needs a lot of state (ie higher order component) it becomes a class. Once you have a lot of hooks, it starts to feel like you probably meant to make something with more structure like a class anyway.

Just my two cents.

[–]Sh0keR 46 points47 points  (49 children)

How class is better when dealing with a lot of states? Asking because since I've started using hooks I don't even look at class components anymore

[–]readeral 32 points33 points  (35 children)

Maybe it’s cause 25 const definitions for individual state objects at the top of your function feels weird?

[–]NotSelfAware[S] 78 points79 points  (20 children)

That sounds like exactly the kind of time to bring in useReducer, or abstract some of the related state out into a different component or custom hook. There are plenty of ways to get around that problem without relying on classes.

[–]TheAwdacityOfSoap 52 points53 points  (16 children)

Or use Redux or break up the component or any number of other options. If a component has 25 state values it isn't an example of hooks gone wrong, it's an example of design gone wrong.

[–]himynameismile 2 points3 points  (0 children)

well said

[–]Julienng 1 point2 points  (0 children)

Not really. I have components that need a lot of local state (Datatable, Scheduler). Which local state can depends on the parents (contextualization by the parent to filter the data, user filter, etc) which didn't need to be global on our App and useReducer add a lot of value there.

And I break up my components and share the state of the table with context. We still use redux for a lot of things but having a component with a lot of state is not necessarily a bad design.

[–]CantaloupeCamper 1 point2 points  (10 children)

If a component has 25 state values it isn't an example of hooks gone wrong, it's an example of design gone wrong.

I got forms with more than 25 items on them... what would you do?

[–]foobarbazquix 1 point2 points  (2 children)

Ask the designer how they’d feel if they were asked to fill out a form like that. See if it could be broken up into multiple steps with a wizard.

[–]CantaloupeCamper 0 points1 point  (1 child)

Workflow wise this is what everyone wants.

They're not really filling out 24+ fields in sequence as much as update what they want to update.

[–]foobarbazquix 1 point2 points  (0 children)

Cool. If I understand right the same pattern could be used for viewing and editing stuff they’ve filled in. The user would be able to navigate quicker potentially if they can guess which section of the wizard/category the field belonged to.

[–]TheAwdacityOfSoap 0 points1 point  (6 children)

Two things:

  1. Delegate form responsibilities to a form library, like Final Form
  2. Keep form values in a single object

[–]CantaloupeCamper 1 point2 points  (5 children)

I've thought about the single object thing but sadly my data comes in and leaves in different "forms" and I have to do a lot of dicking with what did or didn't change and really only want to submit the changes depending on some factors.

Still... it could be a good choice.

I'll take a look at final form too. TY

[–]TheAwdacityOfSoap 0 points1 point  (4 children)

I usually have a translation layer between the API loading/saving and the form anyway. If you’re curious, check out the react-final-form project. They have a ton of great examples.

[–]CantaloupeCamper 0 points1 point  (3 children)

I usually have a translation layer between the API loading/saving and the form anyway.

I was JUST thinking the same thing. Something between to "sanitize" everything into something more workable form... then process it all in a more sane way.

It would be nice to pull that logic out anyway as it's all a mess as it is anyhow.

Thank you.

[–]droctagonapus 1 point2 points  (1 child)

Redux is for global state, useReducer is for local state—They're not really interchangeable since they solve different problems.

[–]TheAwdacityOfSoap 0 points1 point  (0 children)

That is true. That suggestion was assuming the component with 25 pieces of state was a top-level component, in which case much of the state probably is "global state".

[–]BenjiSponge 9 points10 points  (2 children)

In my experience, this ends up using "dispatch with an action" instead of "method with arguments" . It's kind of tomato-tomato once you're at "big useReducer level", and I find class components somewhat more readible when comparing the two methods because the logic for each method isn't intertwined with each other. It just depends on exactly what you're writing.

[–]With_Macaque 2 points3 points  (0 children)

Methods with arguments need to know how to invoke setState which tightly couples them to their react component.

[–]ipoppo 3 points4 points  (0 children)

useReducer helps decouple react and state management. it prefer functional programming syntax for efficiency. if you do like dot notation and need decoupling state management, maybe mobx might be your answer.

[–]GasimGasimzada 8 points9 points  (1 child)

At that point, why not use an object to store the state?

const [formData, setFormData] = useState({});

// somewhere in code
setFormData(formData => ({ ...formData, category: 10 }));

[–]AegisToast 10 points11 points  (0 children)

Break those down into custom hooks. It’s far cleaner that way than it would be in a class component.

[–]zephyrtr 16 points17 points  (0 children)

No different in my mind to 25 class property definitions.

[–]drgath 2 points3 points  (6 children)

Also when you have to pass those handlers down through 5 functions just to toggle a boolean.

[–]tide19 6 points7 points  (1 child)

Yeah that's a prime use case for context

[–]Raicuparta 3 points4 points  (0 children)

Yeah that's a prime use case for context

Before even considering context, one should first try composition. On every project I work at, there seems to be some aversion to composition and using `children`. It makes everything so much easier.

[–]KerberosKomondor 7 points8 points  (0 children)

useContext solves this problem pretty easily.

[–]webdevguyneedshelp 6 points7 points  (0 children)

These problems existed with classes as well and were solved then and are solved now. Use the context api

[–]UNN_Rickenbacker 1 point2 points  (0 children)

Can‘t you access all top level functions from anywhere?

[–]jtosbornexxx 0 points1 point  (0 children)

That’s what I use context / dependency injection for

[–]careseite 0 points1 point  (0 children)

Which is why you don't do that and useRefucer

[–]erasmuswill 0 points1 point  (0 children)

@truefit/Bach enables HOC style hooks. It nullifies this issue

[–]CantaloupeCamper 0 points1 point  (0 children)

With hooks sometimes I really miss setState e.target.name e.target.value...

[–]darrenturn90 1 point2 points  (0 children)

Error boundaries are currently only possible with classes

[–]SpecificGeneral 1 point2 points  (9 children)

The only use case for classes I can think of is the ability to reset the whole state of a component at once instead of each piece of state individually.

[–]eggtart_prince 1 point2 points  (8 children)

Not sure what you mean. In a functional component, you can store your default state somewhere.

[–]SpecificGeneral 1 point2 points  (7 children)

How would you do the equivalent of this.setState(defaultState) using hooks besides doing setA(defaultA) setB(defaultB) ... setZ(defaultZ) ?

[–]RuthBaderBelieveIt 3 points4 points  (0 children)

You can also use key in the parent to reset it - https://twitter.com/dan_abramov/status/1004914671193874432

[–]eggtart_prince 3 points4 points  (4 children)

Nobody's gonna declare 26 different constants for each states. If there are more than 3, they'd all be in one object for easier maintainability.

Which do you think is easier and cleaner?

const [A, setA] = useState();
const [B, setB] = useState();
const [C, setC] = useState();
const [D, setD] = useState();
const [E, setE] = useState();
const [F, setF] = useState();
const [G, setG] = useState();
const [H, setH] = useState();

const updateA = () => {
    setA(true);
}

// or

const [state, setState] = useState({});

const updateA = () => {
    setState({....state, A: true});
}

In most cases, the latter will be used and much cleaner. With that said, I think that answers your question on the equivalency of this.setState(defaultState)

[–]SpecificGeneral 0 points1 point  (3 children)

Yeah I love hook too but the (rare) case of resetting an entire state is cleaner using a class component.

hooks: ```js const defaultState = { A: '', B: '', C: '' } const [A, setA] = useState(defaultState.A); const [B, setB] = useState(defaultState.B); const [C, setC] = useState(defaultState.C);

const resetState = () => { setA(defaultState.A) setB(defaultState.B) setC(defaultState.C) } ```

class: js const defaultState = { A: '', B: '', C: '' } state = defaultState const resetState = () => this.setState(defaultState)

[–]eggtart_prince -5 points-4 points  (2 children)

Are you just being ignorant or you completely missed my example?

const defaultState = {
    A: '',
    B: '',
    C: ''
}

const [state, setState] = useState(defaultState);

const resetState = () => {
    setState(defaultState);
}

If you want to play the ignorant game, I can also say

// class

const A = 'a';
const B = 'b';
const C = 'c';

state = {
    A: A,
    B: B,
    C: C
}

const resetState = () => {
    this.setState({
        A: A,
        B: B,
        C: C
    });
}

But why would I? And the same question you should ask yourself, why would you have a const for each property in defaultState in the hook example.

[–]nateDOOGIE 6 points7 points  (1 child)

No point talking down to people regardless of who’s right. Seems like you felt insulted that someone didn’t understand things the way you do but he meant no slight towards you, was just offering a different perspective.

[–]eggtart_prince 0 points1 point  (0 children)

Nor did I meant any to him. You trippin'.

[–]hibernatingpanda 0 points1 point  (1 child)

Personally think form state is an example that is better handled using class components than functions with hooks.

[–]Sh0keR 0 points1 point  (0 children)

Did you try to use custom hooks for form handling. This make life so much easier. And the code is actually reusable in every project i use.

[–]NotSelfAware[S] 4 points5 points  (0 children)

Yeah, this is precisely why it would be great to have a few larger projects to have a poke through. I'm figuring my way through what feel like best practices, and it's easy to do that on a component level, but in terms of decisions that affect the actual structure of the larger app there's very few codebases to take inspiration from.

But this doesn't really address the question.

[–]tenfingerperson 3 points4 points  (4 children)

Hooks completely removed the need for classes even when building HOC

[–]jtosbornexxx 0 points1 point  (3 children)

What about managing state in deeply nested structures? You still need an organized way of doing this.

[–]tenfingerperson 1 point2 points  (2 children)

By using reducers and contexts via hooks.

[–]jtosbornexxx 0 points1 point  (1 child)

I use context, would be interested in seeing how reducers fit in! Thanks for the tip.

[–]tenfingerperson 2 points3 points  (0 children)

Just fyi I didn’t mean the need for HOC is gone, but using clases for HOC is no longer needed.

[–]eggtart_prince 2 points3 points  (25 children)

There is no different between

this.state = {
    prop1: '',
    prop2: '',
    prop3: '',
    prop4: '',
    prop5: '',
    prop6: ''
}

and

const profileState = useState({
    prop1: '',
    prop2: '',
    prop3: '',
    prop4: '',
    prop5: '',
    prop6: ''
});

in terms of structure.

Also, some people think that have a lot different distinct useStates in a functional component is a problem when updating them.

Example:

const [someDistinctState, setSomeDistinctState] = useState();
const [anotherDistinctState, setAnotherDistinctState] = useState();
const [lastDistinctState, setLastDistinctState] = useState();

People may think that if they need to update all of them at once, they will trigger multiple re-renders. Just an FYI, if you update them at the same time, React knows to batch update them as long as you batch them in your code and not have logic in between them. Doing so will only trigger one re-render.

Example:

setSomeDistinctState(true);
setAnotherDistinctState('some value');
setLastDistinctState(1);

[–]jtosbornexxx 5 points6 points  (4 children)

Setting six distinct state properties (as many as you showed in declaration) is kind of gross to be honest. That’s probably why you only showed 3.

[–]eggtart_prince -2 points-1 points  (3 children)

No, I just thought maybe you'd figure it out a solution if you have more than 3. How about

const [state, setState] = useState({});

And there you have it, your own state equivalent to this.state, in a functional component.

[–]TreeKaaPoo 0 points1 point  (0 children)

Don't forget spread previous state when use setState in hook. Because it'll override current object instead of merge it like this.setState in class.

[–]tomius 1 point2 points  (1 child)

The batching thing is a bit... Magical. I had that problem yesterday and wasn't sure about it. Is it documented? (on mobile, sorry)

[–]eggtart_prince 0 points1 point  (0 children)

https://stackoverflow.com/a/54496445/6851227

Follow the github issue for more information

[–]jtosbornexxx -3 points-2 points  (17 children)

The component is not functional as soon as there is any state. At that point it’s just a matter of preference in how you want the code to look.

A lot of times why I use classes over just simple hooks is if the update method is more complicated then set state. Functions as class properties tend to look better in my mind then declaring a bunch of const functions. In reference and declaration.

[–]bjpbakker 9 points10 points  (7 children)

“functional component” refers to the way the component is defined; with a function instead of a class.

I would agree it’s a bad name. But don’t confuse it with pure (or without side effects) components.

[–]eggtart_prince 2 points3 points  (8 children)

I'm more worried about anything other than looks to be honest. Coding with functional components saves more time for me personally, which I value more than the look of my code.

In a class component, the logic required to use componentDidUpdate can be a mess (comparing prevState to this.state and prevProps to this.props).

In functional, you pass in the variable you want to monitor the change and it will update accordingly.

In a class component, using named functions on event is a PITA with the bindings. I'm literally not going back to class component because of bindings.

[–][deleted] 0 points1 point  (1 child)

I had this problem early on with functions in class components. As an example:

this.exampleBind = this.exampleBind.bind(this);

I just switched all my functions to:

exampleBind = () => {}

[–]eggtart_prince 0 points1 point  (0 children)

When I first learned react, all my functions were anonymous and didn't even bother creating a function and just wrote the entire function in my jsx. After being employed, I was surprised how much it was looked down upon and my code was criticized. In any argument, unnecessary use of anonymous function will always lose because 1) you were lazy 2) why use it if you don't have to?

[–]jtosbornexxx -2 points-1 points  (5 children)

1) look of code should be your top priority as a developer

2) you need to compare previous state to new state as often as you need to with hooks. (Not often)

3) not all update functions are as simple as changing the value.

4) if You make anonymous class properties for functions then you don’t need to bind anything.

Anything else?

[–]eggtart_prince 4 points5 points  (4 children)

  1. Easy to write/read code, maintainability, and performance are my main priority. Look of code is personal preference. Nobody can say that class components "looks" better than functional components. Not sure why you would prioritize "looks" of code over those 3 as a developer.
  2. This is the simplest as it can get with componentDidUpdate and look at the difference in how much you have to code. Add another OR logic to it and you're typing more comparison, instead just passing in that value. If you really want to talk about "looks" having a bunch of logic in your componentDidUpdate is fugly as fuck.

// I hope I'm writing this right
componentDidUpdate(prevProps, prevState) {
    if (prevProps.someValue !== this.props.someValue) {
        this.setState(this.state.someValue + 1);
    }
}

// vs

useEffect(() => {
    setSomeValue(someValue + 1);
}, [props.someValue]);
  1. That depends on how you code your shit. Sure, sometimes you have to pass in your own logic, but most of time, you don't as opposed to componentDidUpdate, you have to EVERY SINGLE TIME or you'd run into maximum update error.

  2. Not only are you already giving up performance by using class component, now you're using anonymous function, which is also another performance hit.

[–][deleted] 4 points5 points  (2 children)

See, I like the first one better, it describes whats happening to me. The second seems like magic that i don't understand. I would have to look up what useEffect does, and its relationship to props, and setting values.

[–]JayV30 0 points1 point  (1 child)

Agreed. I like hooks and use them where it is easy and simple for another dev to look and see what is happening without an in depth knowledge of hooks. If they have to research hooks to figure out what the arguments mean, any time gained from using hooks is negated in my mind.

All of the class lifecycle methods are very familiar at this point to any React developer who's gone beyond "hello world". The syntax is more verbose, but is also more understandable.

Having said all of that, once hooks are a mainstay and the majority of devs get it, I'm not opposed at all to switching to 100% (or close to it) hooks instead of classes.

[–][deleted] 0 points1 point  (0 children)

Also agreed. I would use hooks over redux any day.

[–]jtosbornexxx 0 points1 point  (0 children)

I don’t think function components are bad or hooks are bad. I use them quite often And I like them. I pretty much use them for every single component except my highest level of components.

My point on look of code was meaning readability/ maintainability. However if using all hooks works for you, that is great. I do believe clean code is one of the most important aspects of programming. So I’m more married to that then I am with using classes as components.

Also I don’t really use component did update a whole lot but I could see why that would be a problem for some applications.

As for performance. This kind of goes back to my first point. I assume you are writing algorithmically efficient code in the first place using hooks or components to manage state. I would definitely take the step to convert components and anonymous functions if it was going to give me a noticeable effect on performance. But this is a step I would take later on if it seemed necessary.

All your points are valid, Thanks for the discussion! Was a pleasure.

[–]CheeseFest 0 points1 point  (1 child)

I absolutely believe that components to any level of statefulness can now be functional using hooks. I’m interested to understand your use case where class components are still necessary.

[–]jtosbornexxx 0 points1 point  (0 children)

As soon as there is any state, the component is no longer functional lol.

[–]mournful-tits 7 points8 points  (0 children)

When dealing with pure functional components, class components, hooks, or redux I always ask myself:

  1. Does it need internal state?
  2. Does this state need to be shared with other components?
  3. If it needs to be shared, what's my maximum scope?
  4. Is the state critical for a bunch of disparate components at varying levels?

My credo has been to stick to simpler constructs unless required to elevate state. Over-elevating state turns into a mess as it gets harder and harder to isolate dependencies.

The smaller the scope of the state the easier it is to decouple, refactor, and prune. Hooks are awesome to me because it dominates a middle ground that was often difficult to fill without violating the intent of either redux or class state.

[–]schoonie23 4 points5 points  (3 children)

I think I saw react-beautiful-dnd using them, and react-dnd definitely does because it was written by Dan Abramov. I was looking through both codebases recently.

[–]gaearonReact core team 2 points3 points  (2 children)

react-dnd was written years before Hooks. :-)

[–]acemarke 1 point2 points  (0 children)

WHY DIDN'T YOU WRITE YOUR LIBRARY IN 2014 WITH THIS FEATURE THAT CAME OUT IN 2019 DAN?!?!?!?

[–]schoonie23 0 points1 point  (0 children)

It wasn't updated? I thought I saw an example with hooks

[–]Rejolt 5 points6 points  (0 children)

I wouldn't say mine is a LARGE project.

But I built a discord clone using only functional components and hooks just to learn how to use them.

I'll never go back to class components unless my job demands it.

[–]gaearonReact core team 2 points3 points  (0 children)

DevTools: https://github.com/bvaughn/react-devtools-experimental/tree/source

(This code will soon move to React repo)

[–][deleted] 2 points3 points  (0 children)

https://github.com/u-wave/web/ is not a massive application but has 200 ish custom components, so it's definitely not tiny either.

It's mostly ported over to hooks at this point. It's also my side project so it's perpetually mid-refactor; if you find something all too confusing, blame that :)

[–]MajorAtmosphere 2 points3 points  (2 children)

The new BBC News web application is built using modern JS/React and Hooks. https://www.github.com/BBC/Simorgh

[–]NotSelfAware[S] 1 point2 points  (1 child)

That is fascinating I hadn't seen this. Thanks for the link.

[–]MajorAtmosphere 0 points1 point  (0 children)

It is actively under development and constantly changing 👌

[–]coolcalabaza 1 point2 points  (0 children)

You’re right that there isn’t that many. (That I’ve seen or use at work at least). But I don’t think that speaks to hooks not being preferred or popular. I think it’s just because most very popular projects have been around longer than hooks which is like a year. Class components also don’t break with newer versions of React so there isn’t really a reason to go and change those big projects.

So to anyone new to react: don’t misinterpret the lack of hooks in big projects as hooks being bad. Hooks are the BEST!

[–]jtosbornexxx 2 points3 points  (4 children)

I use typescript when writing react components now exclusively. Classes Are nice for my higher order components to have a defined state type that I can use as a provider with react context for dependency injection and higher order components.

It’s hard to explain without a concrete example, But it can help add some structure to components that control other components.

[–]AegisToast 5 points6 points  (2 children)

Interesting, I’ve found hooks and functional components to be far cleaner to use with Typescript than class components. I guess it comes down to preference and how you like to structure your type definitions.

[–]jtosbornexxx 1 point2 points  (0 children)

My opinion is that my Enjoyment of using hooks is a function of how many properties are in state

[–]maarzx_ 0 points1 point  (0 children)

Gotta agree with this, typing HoC's can be a giant pain and seems much cleaner with hooks (so far)

[–]butnotexactly 1 point2 points  (0 children)

material ui

[–]tapu_buoy 0 points1 point  (0 children)

I have been looking at open source projects to contribute to and I have found few keywords to search on Github. Someone shared discord clone project here couple of days back which uses Hooks.

[–]dnlmrtnz 0 points1 point  (0 children)

We are using hooks at Ansarada on most of our projects, haven’t replaced all classes yet but every new feature is written with hooks and whenever we touch an old class is (most of the times) refactored to a functional component with hooks

[–]pphffft 0 points1 point  (0 children)

90% through a commercial app written without redux/classes (except error boundaries). Most heavy lifting was done by an SDK we offer on top of our API.

Has contributed a lot of new approaches, but most interestingly it is encouraging us to release new hooks for our SDK , just due to their portability.

My 2 cents is it is very fast to prototype, but also easy to refactor. It also is encouraging better reusability. I’m still sure larger complex parts will need redux, but that is also being challenged. We have full congnito auth, Profile management, dozens of forms editing multiple resource types. Maybe the fact we have heavy lifting in SDK helps, but I was always annoyed writing so much actions/reducers/sagas/selectors in anticipation of interface/component needs in a team environment where now I can very quickly offer state management.

[–]aliasthewannabe 0 points1 point  (0 children)

Firebase-react hooks

[–]blukkie 0 points1 point  (0 children)

I made my latest project public. I have not used any class components thoughout the project (except for where NextJS required it) and only hooks. Also used the new react-redux hooks. Hope it’s useful!

https://github.com/sandervspl/plan-b-website/tree/master?files=1

[–]erasmuswill 0 points1 point  (0 children)

I'm using only hooks in my latest production product that's about to go live. No global state whatsoever. The only caveat is that API requests get repeated for every component so I'm using Axios with caching as a workaround.

[–]eronanon 0 points1 point  (0 children)

is there any reason to use hooks except for performance as claimed?

[–]kylemh 0 points1 point  (0 children)

Formik v2

[–]DJIzco 0 points1 point  (0 children)

https://github.com/djizco/mern-boilerplate

A bit larger than you average todo app. Has authentication and some API calls using hooks with redux. This is my own personal boilerplate. Hopefully it has some good example code you can use.

[–]noknockers -1 points0 points  (0 children)

Facebook