Hacker News new | past | comments | ask | show | jobs | submit | prodave's comments login

Aren’t hooks more confusing than the class components? In a class, you write your initialization code in the constructor - no infinite loop if you fetch something. And anyone who has used classes in Java or other languages would feel at home.


In my 1.5 years or so of using hooks, I'm finding components with hooks subtly more buggy than their class counterparts - there are a lot of gotchas with that dependency array for hooks, I have encountered nasty bugs both with explicitly declaring all of the dependencies in the array and declaring less than them.

It is much easier to accidentally create infinite loops with useEffect that you would never create with class components, and some of the code you write turns out to be more verbose and less expressive, such as when trying to diff previous and current values of state & needing to create extra state variables with useState for each such value you need to react on.

Hooks seem very appealing at first (I lean more FP than OOP in general), but the bugs and slipshod initial rollout out of beta really does not inspire much confidence. Even today I still encounter weird issues.


The biggest difference is that the class based components are an older iteration of the API into React, one that lies closer with how React internally works (or worked), but one that is not necessarily useful for writing correctly working components.

Say you have a component that renders some data it fetches from the backend, and it received the ID via a prop. In a class based component you might be inclined to write the fetching logic in the componentDidMount or maybe the constructor. However, if you change the ID you feed the component, the component will update instead of being recreated. In the naive class based version it won't refetch the data, and won't behave correctly. With useEffect hooks you don't really care anymore, you can reason about side effects in the same declarative way. You express the fact that fetching new data is a dependency of the prop changing, which holds true both on first render and later on update.

The hooks API fixed a handful of these 'mistakes' that were still present in the class based API. I agree that the syntax might look awkward at first, but the hooks API is much better thought out than the class based one.

(Some anecdata: almost any component that I rewrote in hooks-style has been halved in number of lines of code, the concepts have been much less spread out over the file. See this tweet for an example: https://twitter.com/threepointone/status/1056594421079261185)


No, you use componentDidMount etc, spreading out the logic that could go into a single hook into multiple lifecycle methods, spaghettied with other logic. Hooks are much cleaner.


Adding to this, hooks make it much easier to pull related state management code out of the component. They help make state logic just as composable as UI logic.


Would it be possible to have a single method on a class that behaves like whatever useEffect is doing?


Not in a single method, no. Watch this talk for more details! https://www.youtube.com/watch?v=wXLf18DsV-I


Well, I did something a bit similar my own language: https://github.com/batiste/blop-language/commit/90e7704e125f... Not sure where classes are an issue with doing anything like this


I've worked with both extensively, hooks are way easier to grasp, they allow you to avoid numerous ifs and comparing manually to previous states, you can separate actions according to what properties you're listening changes on, which would be cobbled together in a traditional life-cycle method, and the best part? They can be reused between components


My superficial understanding is that React components as classes are far more complicated than they might seem at first. You're not in control of creating the class instances, rendering them or destroying them. React is in control of that.

The constructor is the wrong place for data fetching in React class components as far as I remember anyway. I don't remember the exact reason, but it always has been somewhat non-obvious and you always needed to understand the React lifecycle to avoid bugs in that kind of code.


Classes in React are confusing because they aren't actually classes, just something shoehorned into classes. For example you wouldn't write your initialization code in the constructor, you would do it in componentDidMount.

Classes in React generate false expectations.


Yeah but how is that different from any other UI framework?

onCreate/onStart/onResume and onComponentDidMount, onPause/onStop/onDestroy and onComponentWillUnmount are basically the same. Be it Android, Swing, or Qt, everywhere it's the same pattern.

React is the first framework which actually feels like UI development on the web, not anymore like JS spaghetti.

In fact, having internal state, externally given props, exposing events, and being declared through markup is exactly the same between React, Android or Qt.

The only thing React brought to the table was allowing you to basically just recreate the children every time something changed, and it'd diff automatically.

For us native devs this thread is hilarious, because it's just JS decs complaining over things we've always done


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

> JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

You've been tricked into thinking you're using a class, but you're really not. I understand it's a useful trick, but hooks are more idiomatic for JS as a language.

As a side note, one of the problems with JS is that the community often disagrees about what JS is: https://babeljs.io/blog/2018/07/27/removing-babels-stage-pre...


I disagree. I think that's like saying C++ doesn't actually have classes, it's just syntactic sugar around structs of function pointers.

It may be technically correct, but C++ and now JS have a "class" keyword for a reason, and that's to steer you towards organising your code into classes which operate in certain ways. In both languages you can avoid using classes, sure, or abuse classes in various ways. But fundamentally they do have classes.


> steer you towards organizing your code into classes which operate in certain ways

But that’s the point. The way in which classes operate in JS is different from the way classes operate in OOP focused languages like C++, Java and C#. That’s because the language doesn’t have classes, but rather syntax to make it look like it does. On the surface your code will be organized in similar ways but the underlying behavior is different.


But what good are classes if you're not doing object-oriented programming? React classes are just stateful wrappers around a pure render function. It's not idiomatic and frankly dangerous to do anything you would with a regular ES6 class with a React.Component.


Can you clarify on that last point a bit? Not that I extend React.Component these days, but far as I'm aware, the only "gotcha" of React.Component (vs other classes in JS) is that they shouldn't be extended.

I guess, yes, there's different semantics between the constructor and componentDidMount, but it's UI library, this is common that "when a constructor is call there is no guarantee the component has actually mounted".


Sure, what I mean is you'd never use a React.Component like you would a class in Java or another OO language. You never instantiate it, pass instances of it around, or call any of its public methods. It serves just as a container for some functions and provides a binding for `this`. Dealing with `this` caused things like componentWillRecieveProps to be buggy so hooks allow you to use a function as the container and remove the need to reference `this`. The move from classes to functions was not a paradigm shift just a different implementation of the same approach.


You can definitely pass them around and call public methods on them using refs, that's what useImperativeHandle is mimicking.

Was the issue with `this` in componentWillRecieveProps not solved by using an arrow function? If so, that just sounds like normal JS binding woes.


Actually, you can pass instances of it around just fine, if you know how it works. It’s not any different than a view subclass on Android, or a widget in Qt.


Instantiating it does nothing useful, though. `React.Component` is basically an empty shell with a marker flag on it so that the React renderer recognizes it, and the `setState` method just delegates to the actual renderer implementation. There's no reason to ever instantiate it yourself.


But that's the point. All UI frameworks are like that.

You can't `new MyRecyclerView(...)`, you've got to `LayoutInflater.inflate(MyRecyclerView, parent)`, which isn't any different from `React.render(MyApp, parent)`.


> as I'm aware, the only "gotcha" of React.Component (vs other classes in JS) is that they shouldn't be extended.

Facebook recommend composition over inheritance, but you can totally extend React.Component and even get abstract classes involved. In my custom React renderer, all the components in the library are based off React.Component class inheritance.

https://github.com/shirakaba/react-nativescript


I think lifecycle methods in general, no matter what the framework is, are a suboptimal way of doing things. React works quite differently and shoehorning it into a lifecycle thing was holding it back, or at least that's how I feel. YMMV.

At least it looks like we agree that React is a decent framework :-)

That said, for us devs who do both native and JS code, the condescending part is quite hilarious as well ;-)


I'm doing JS (vanilla and with React), Android and native (well Qt) myself.

It's just funny when pure JS devs go all "no you won't convince me to compile my code / use classes with lifecycles / etc, that's against the natural order!!!"


I liked that model because as an ASP webforms developer the class lifecycle is easy to reason about, like a page lifecycle.

In ASP you wouldn't put initialisation code in the page constructor either, it would go in Page_Init, Page_Load, etc.

Of course the tooling there made it both easier to put in the right place and harder to edit the page constructor to stick it in the wrong place.


I remember ASP.NET Webforms, and the reason most of the community moved towards MVC-ish frameworks is exactly that most of the time, you ended up shoehorning functionality into different lifecycle methods, which made them much harder to reason about. Most of the time, for anything more complex than just performing the initial databinding, you'd just be looking at the lifecycle chart and trying to figure out which place would be best to put which part of your code. Page_Init? Page_Load? Page_PreRender? I remember the pain of trying to add dynamic controls to a site right in time before ViewState was hydrated but AFTER something else had happened.

I agree that for the easiest of use cases, lifecycle methods make sense. But you very quickly leave that comfortable zone and then it just becomes painful and confusing.


Don't worry, I'm not espousing lifecycles as a panacea or solution for the modern programmer, I just wanted to share that experience with lifecycle methods meant that I was less tripped up by the pitfalls of react lifecycles.

Less so than I've been tripped up by react hooks certainly so it's been a surprise that many here are describing them as being much easier and simpler than classes.

Classes had limits and some pitfalls but it's been frustrating that lifecycle methods have been retired and deprecated because sometimes they felt like the natural place to do something.


> And anyone who has used classes in Java or other languages would feel at home.

Not really because there's nothing object oriented about React.Component. It's just a wrapper for a function implemented as a class.


THIS is what I wish I knew about React. As a Java user, I made incredibly wrong and damaging assumptions because "classes, I know what these are"! I still can't make heads or tails of hooks, but in due time!


Imo, hooks present an API that is much less difficult to internalize, but maybe holds your hand less? I used react for a few months on a sideish project and had trouble knowing which component method I needed for something, whereas with react now it's all covered by hooks.


Class components feel like a spaghetti mess to me whereas Hooks are obvious, straightforward, and clean. I understand that others feel differently but I personally cannot stand working with class components.


[flagged]


Hooks don't change the meaning of const. The whole render function is re-run each time something is modified. There is ZERO internal mutation going on in render functions.

I suggest researching and learning how something actually works before calling someone else's work a "dirty hack" or "f'ing joke".

(And afaik hooks were Sebastian Markbage's idea... f'ing genius if you ask me)


Wow, posts like these provide real counterweight to my desire to write open source software.


[flagged]


There is a difference between critique and attacking people.


const is for assuring that the variable is never reassigned. It's not for assuring that variable cannot change.

const is not "constant".

In any case, in the useState hooks, if the value is changed via the set function, the component will be diffed and re-rendered. There is no value change happening while it is running in that scope.


> It's not for assuring that variable cannot change.

Please tell me how you'd change a to 1 in this example:

  const a = 0;


You can't do that. Just like you can't do:

    const [count, setCount] = useState(0); 
    count = 1;

In both cases, const is const.

The fact that `setState` modifies state outside of the local scope does not mean that a local variable is not const. This is really basic programming, it doesn't have anything to do with React.

Here's the exact same scenario without React to show why you're wrong in your original comment:

    const foo = () => {
      const bar = getBarFromDatabase();
    }
Imagine that this is a typical database where values can change, so that every time `foo()` is called, `bar` can have a different value. Do you think that this is a dirty hack that is overruling the const type declaration as well?


> This is really basic programming

No, it's not. React is iterating that piece of code of your function internally to modify the value of the const, there is no other way to do it. And it is especially confusing because you can use that const 'variable' in the scope representing a changing value. And the change is magically made by its 'setState' method.

If you do this yourself in a loop then it is of course totally clear what's going on, but now we're writing functions where parts of it are being iterated by React, and that's not functional at all, IMAO it's a hack.


React does not "iterate over parts" of your functions, it simply calls the entire function. There is no magic happening.

You've already received a lot of responses explaining how both const works (which you still seem to misunderstand) and how React works, I hope you can take this as an opportunity to learn and perhaps not be so confident in the future when criticizing something that you clearly haven't taken time to even understand at a basic level.


I really recommend learning more about what you're complaining about before arguing with people about how you think something works.

Your jargon doesn't even make sense. "iterating that piece of code in your function"?

Put a console.log() at the top of your function and you'll see that it's simply being called many times.


You don't. The closure ends, the stack is popped, `a` is disposed, and then, in another closure, you have this line:

    const a = 1;
`a` was never re-assigned, but the value of the variable we call `a` changed. I think the key here is knowing that if you have the following:

    function Foo() {
      const [a, setA] = useState(0);
      return <span>{a}</span>
    }
`Foo()` will be called on every render, `useState` will only use its argument the first time it's called (and then after that just remember its value), and `a` will be a "new `a`" every time, after which, like all variables declared in a function, it's discarded when the function returns.


Your example is a bad one.

  const a = { prop: "value" };
  a.prop = "different";


Do de-googlers consider Startpage to be acceptable? The results are from google but they claim that your privacy is protected.


Startpage was also bought by an advertising company.

They might claim privacy, but de-googlers forget that Google is a much bigger target for law enforcement than any of its alternatives.

If you don't trust Google to not collect your data, in spite of turning that behavior off in your profile, why would you trust Startpage?


Pretty questionable.

A listing of search alternatives, including Qwant (French-based, so EU/GDPR), SwissCows, SearX, and others, with good rationales:

https://restoreprivacy.com/private-search-engine/


Hi - Startpage person here. Maybe I can clear some stuff up.

1) Startpage provides Google results, but Google never sees you. Startpage submits your query to Google anonymously, then returns Google results to you privately. For more info on we keep your search private: https://www.startpage.com/blog/privacy-awareness/how-does-st.... 2) Startpage is HQ'ed in the Netherlands, meaning we don't have to comply with US government or law enforcement and comply with EU/Dutch privacy laws such as GDPR. Also, we’re not likely to receive requests by governments to hand over user data – simply because we don’t have any. 3) In 2019, Startpage announced an investment in Startpage by System1 through Privacy One Group, a wholly-owned subsidiary of System1. With this investment, the plan is to further expand privacy features and reach new users. (Lots of new privacy features in the works!) The Startpage founders have control over the privacy components of Startpage. And! After conversations with the privacy community, Startpage was recently relisted in PrivacyToolsIO. More info on that: https://support.startpage.com/index.php?/Knowledgebase/Artic...

That's a lot of text, but I hope it helps.


As c-suite exec, better to be incompetent during the good times than to be competent during the bad times. makes sense that he’s leaving.


Personal attacks are not ok on HN, so please don't post like this. Maybe you don't owe a c-suite exec better, but you owe this community better if you're posting here. We're trying to stave off the default internet degeneration, to the extent possible.

https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...

https://news.ycombinator.com/newsguidelines.html


Side lessons seems to be that scammers have access to a lot of your personal info, which can fool you, and that you should never ever give an OTP over the phone.


One-time PIN for the curious


Is the business model basically a funnel to loans and other credit products? The section showing a VP buying a house makes it seem like it is.


Yes. All the tools are 100% free and accessible without doing anything with regards to financing, though. We're not pushy about it either :-)


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: