4 ms·
React's hooks (and some JSX style things in general) are quite pernicious there because they essentially break JS: you can't use them inside an `if` or a `for`
by ljm 6y ago
React's hooks (and some JSX style things in general) are quite pernicious there because they essentially break JS: you can't use them inside an `if` or a `for` or a `while`, or even within another function. You're no longer writing Javascript, you're writing a restricted subset to avoid undefined behaviour.
That alone is a concern, because any junior programmer getting an introduction through React is going to get a twisted understanding of the language itself.
- brundolf 6y agoIn some ways JS is an excellent first language- beyond its broad applicability, it has an extremely "average of all the others" set of features and primary syntaxes. An experienced JS programmer will be conceptually comfortable with Python and Ruby, syntactically comfortable with Java and C, etc. But in terms of the industry-standard practices/ecosystem, it is a terrible first language if you want to gain a generalized understanding. What you describe here is extremely true; I've seen it in practice: > any junior programmer getting an introduction through React is going to get a twisted understanding of the language itself I've talked with otherwise very capable JS devs who have built impressive things with multiple frameworks, but don't have a good handle on fundamental concepts like the difference between the two kinds of function syntax (they may have only ever used one), how Promises behave outside of a narrow subset of situations, what NodeJS actually is (despite having used it), or even the difference between passing by reference vs value. Many of these frameworks create such a narrow lens into the language itself, add what are effectively (sometimes literally) their own DSLs on top, sprinkle in some magical behavior, and when all is said and done you hardly end up using JS at all. Obviously there's a benefit from doing things this way or it wouldn't have happened. But I can't help but think the technologies that work well for industry are having a detrimental effect on a generation of new programmers.
- searchableguy 6y ago> even the difference between passing by reference vs value You can only pass by value in JS so maybe that's why. It is a bit confusing because of how objects work that it feels like you are passing by reference. You are passing reference as the value.
- brundolf 6y agoWhen it comes to primitives you can only pass by value, but with objects and arrays you can only pass by reference. And this applies to comparisons too: when comparing objects or arrays you are comparing by reference, not deeply by their inner values. If you want to compare them deeply you have to take some additional steps to make that possible, and all of the different strategies for doing so have different trade-offs. I once talked to someone with >5 years front-end experience, including some team-lead experience, who thought the difference between == and === was that === compares objects deeply. That is very, dangerously wrong. The only way I can imagine he got by for so long with that misconception is that he'd always used ImmutableJS.
- Scarbutt 6y agobut with objects and arrays you can only pass by reference. It's still pass by value, you are passing the reference of the object as a value.
- brundolf 6y agoI'm not sure I agree with your framing of the precise terminology ("passing a reference to an object, by value" vs "passing an object by reference"), but it also isn't important. What's important is this: let a = { foo: "bar" } let b = { foo: "bar" } console.log(a === b) // false and this: let a = { foo: "bar" } let b = a b.foo = "blah" console.log(a.foo) // "blah" This is the kind of misunderstanding that causes insidious bugs.
- slibhb 6y ago> I'm not sure I agree with your framing of the precise terminology ("passing a reference to an object by value" vs "passing an object by reference") The distinction is that, if JS truly was pass-by-reference for objects, you could change what the reference was pointing to. But you can't. I agree with you that objects/references are a stumbling block for new programmers in JS. You have to understand how these things work but there's no explicit concept of a reference, which means it can be tricky to learn.
- deleted 6y ago[deleted]
- wwweston 6y agoI definitely think the tendencies you’re describing are maximized in the JS ecosystem, but it isn’t clear to me if it’s something about the specific language or culture/tooling... or if it’s just where so much of the industry grunt work is getting done. And so much of the industry everywhere is about “do X to get Y result” and any further reflection is kindof a luxury. How does your package manager work? Part of the point is not to know, which works until it doesn’t. So we all get trained into basically a culture of issuing commands in a manner not too different from the machines we ask to do the work, and developing a model of what’s going on is either bonus study or earned by running your hands over the sharp edges when you’re bucked onto the unhappy path. Which definitely happens outside of JS. I suspect it happens more inside because JS functions as maybe the biggest funnel into the field.
- com2kid 6y ago> but don't have a good handle on fundamental concepts like the difference between the two kinds of function syntax There is more than 2 now. :) You have the keyword function, you have const myFunc = (param) => { //body } and then you have the various types that can occur within a class, which can have a little bit different behavior based on which syntax you use. Fun times! And remember, arrow functions within a class have a this, but arrow functions outside of a class don't have a this!
- feross 6y ago> And remember, arrow functions within a class have a this, but arrow functions outside of a class don't have a this! This is not correct. Arrow functions have the `this` value of the outer context. I recommend this article to understand `this`: https://web.dev/javascript-this/ https://web.dev/javascript-this/
- com2kid 6y ago> This is not correct. Arrow functions have the `this` value of the outer context. You are correct, I wasn't clear. I was describing the end effect of free floating arrow functions VS an arrow function declared within a class. When free floating, trying to access 'this' can (will) result in unexpected behavior, when inside a class arrow functions operate exactly as people expect a class member function to operate in other languages. (In contrast to having to otherwise bind JS functions to 'this') In both cases the arrow function is acting the same way, but most intro to JS lessons don't explain it. Indeed the way it was originally explained to me is that "arrow functions in classes auto bind to this" which is hilariously inaccurate, but the end effect is as if that was happening.
- michaelpb 6y agoVery true, while I appreciated React Hooks for making React easier for beginners by avoiding the giant can of worms that is OOP mechanics in JavaScript, they are also very magical and even more framework-specific. That said, vanilla JS can be hard like this as well, especially as "solved" legacy issues still regularly crop up in tutorials and code-bases. Many times I remember helping newer folks with challenges they found online that seemed to them like they were testing hard computer science problems, but were more just trivia to navigate some bad design decisions of JS (eg gotcha problems on "this" / binding, IFFE, hoisting, async/promises/callbacks, to name a few)
- nsonha 6y agoI decided that react was going down since the introduction of hooks. Before that I was using higher order component (hoc) perfectly fine and there was even libraries like recompose/recompact that made HOCs more convenient. They're really just functions (no magic, not like quote unquote) and they don't invite devs to convert everything into them and break portability/separation of concerns like hooks do. They're also highly composable (there are no such thing as rules of HOCs), you can pass HOCs as params or put them in conditional code branch or whatever you feel like.