
JavaScript fundamentals before learning React - rwieruch
https://www.robinwieruch.de/javascript-fundamentals-react-requirements/
======
ggregoire
Another basic ES6 trick that beginners usually don't know:

    
    
      handleChange = event => {
        this.setState({ [event.currentTarget.name]: event.currentTarget.value })
      }
    

So you can handle 10 inputs with the same handler.

~~~
coltonv
This is great, and a strategy I used a lot in my last code base. If you do
this for statically typed JS though, you'll get either error messages or bad
typing with lots of `any`s and weak type checks.

Here's a great strategy to do the same thing with strong static types, like in
flow and typescript:

    
    
      setTextField = (name: 'name' | 'email' | 'phone') => (event: InputEvent) => {
        this.setState({ user: { ...this.state.user, [name]: event.target.value } });
      }
      
      setBooleanField = (name: 'isCool') => (event: InputEvent) => {
        this.setState({ user: { ...this.state.user, [name]: event.target.checked } });
      }
      
      render() {
        <div>
        	<input type="text" onChange={ this.setTextField('email')} placeholder="Email" value={this.state.user.email} />
        	<input type="checkbox" onChange={ this.setBooleanField('isCool')} checked={this.state.user.isCool} />
        </div>
      }
    
    

More verbose than the non-typed version, but simpler than declaring a function
for every field with all the goodness of strong static typing.

------
rwieruch
Hey, author here :) I am curious about your experiences using/learning React.
Are there any other JavaScript topics which are important when starting out
with React? Would be great hearing your opinion!

~~~
sorahn
It’s worth noting that using the fat arrow syntax for class functions make
them exponentially harder to unit test because they do not exist on the
Prototype of the component, but are instead only initialized when the class is
initialized.

If you are trying to unit test a function that calls another function in the
same class you cannot mock the second one it if it is a fat arrow.

~~~
dvlsg
I feel like testing things by replacing pieces of a prototype would be fairly
fragile anyways. Is there a reason you couldn't use some form of composition
to mock / abstract your dependencies instead?

~~~
sorahn
Given this super contrived example:
[https://gist.github.com/sorahn/2b287c2a97a12e318585e84d9a9e8...](https://gist.github.com/sorahn/2b287c2a97a12e318585e84d9a9e837e)

If 'baz' was a fat arrow function, you would never be able to test bar in
isolation.

for example: Jest is set up so it's super easy to say `jest.spy(Foo.prototype,
'baz').mockReturnValue('whatever')`and test that bar is doing the right thing.

~~~
Touche
Mocking should only be used for extreme circumstances. This class is very easy
to test without mocking. `bar` takes no arguments and has no external
dependencies and therefore should always return the same result.

~~~
sorahn
OK, you caught me, give bar an argument. (I'll edit the gist)

Why should mocking only be used in 'extreme circumstances'? I want to test
what bar does, and I don't care what baz does, and if someone breaks baz, my
unit tests for bar shouldn't fail, because it is doing its job.

I would mock it if it was calling some function in another module, so what's
the difference if it's calling another function in the class?

~~~
yorwba
Mocking a component means that you now have two places where that component's
behavior is specified and they can diverge. To prevent that, you'll need an
integration test where the components interact directly. Just not using a mock
is enough to get such an integration test.

Then the value of the original, mocked unit test is questionable. It only
provides additional information in the event that the mock differs from the
actual component. If that's unintentional, then either the component is wrong
(which should be caught by the tests for that component) or the mock is wrong.
In either case, the mocked test provides little or negative value.

Then the remaining case, where mocking is actually useful, is when the mock
_intentionally_ shows different behavior. Mocking a slow computation to return
the result instantly. Deliberately failing, to test error-handling code.
Simulating unlikely events in general. Those are good uses of mocking.

TL;DR: Write more integration tests instead of unit tests with mocking.

~~~
sorahn
> TL;DR: Write more integration tests instead of unit tests with mocking.

Interesting. I will investigate what that looks like at work tomorrow. Thanks!

------
lmiller1990
I had the chance/experience to train a new team in Vue.js (and thus modern JS)
which I imagine is similar to people learning React. I noticed the same thing
as the author - the new JS frameworks are "all about JavaScript". Without a
solid knowledge of how JS works, and ES6, learning any of them is difficult.
When realizing this, the main things I focused on what getting people to
understand JavaScript, _then_ start to make use of the framework's more
powerful features.

I also noticed a lot of people interpreting `const` as "you can not change
this, ever". It is short for constant, after all.

~~~
noir_lord
This was my personal experience learning Vue, I didn't know as much about JS
as I thought I did.

I went back and started again filling in all the gaps I obviously had.

A year later and the frontend for all my stuff at work is TypeScript classes
over Vue components and the code is actually _simpler_ to understand.

I learnt something and the code got better, a win/win like that is rare ime.

------
austincheney
The biggest fundamental is that you only rarely need _new_ (when forced upon
you by a bad API) and you don't need _this_ (not ever).

That statement has worked well for me in this language. I know it causes many
people to cry and get immediately angry. The bottom line is that they increase
the verbosity (substantially) of code, they are completely optional, and they
often compound code maintenance through a more convoluted flow control.

~~~
Silhouette
I can understand not liking `this` in JavaScript, but it seems optimistic to
say you never need it. If nothing else, you are bound to encounter large
amounts of code that uses it, so being familiar with its behaviour is
necessary to understand that code.

~~~
DonHopkins
"... but it seems optimistic to say you never need it. If nothing else, you
are bound to encounter large amounts of code that uses it"

Wait -- JavaScript now supports "it"??! Can you iterate over "them"? At least
it's not gendered, so you need to use "him" and "her" and "it" depending on
the object's gender, or just keep everything in a collection so you can use
"them".

------
jvain
Shouldn't the doFilter function use query instead of this.state.query?

    
    
      const doFilter = query => user =>
        query === user.name;

------
wild_preference
This article has a lot to offer a JS + React beginner so it feels lame to
reply to some tiny part of it, but this bit is a constant error propogated in
the ecosystem:

> Even though it is possible to mutate the inner properties of objects and
> arrays when using const, the variable declaration shows the intent of
> keeping the variable immutable though.

let and const only control mutability of the reference. They say nothing of
the value mutability. const then can only be a signal that you are not
reassigning to the identifier.

const is still useful as a default of course since reassignment is generally
the exception.

Maybe this is what they meant but the language used made it seem otherwise.

~~~
Swizec
Beginners don't know about references. What you say is exactly what the author
meant.

~~~
rwieruch
Author here {: Yes, what you are saying here is what I meant. I didn't want to
mix in the whole topic around "passing by value or reference" in this short
teaser.

Hi Swizec :wave: :)

~~~
pygy_
Hi, Robin.

Then you may want to say that `const` guarantees that the name will remain
bound to that object.

The great-GP is correct in that `const` has nothing to do with immutability
besides that. It doesn't necessarily conveys an intent of inner immutability.
It just states that whatever is in the variable will stay there until it goes
out of scope.

Using `const` whenever possible is good advice, off course.

~~~
ravenstine
It's been astonishing to me how people switched from var to let, but seem
confused as to when to use const. I use const wherever I can since it's more
appropriate for non-changing variables, and it helps me more easily visualize
how a variable is being used in a block. But in other people's code I see a
lot of letting all over the place. Maybe it's because of those articles saying
to use let instead of var, but glossing over const.

~~~
mygo
maybe it’s because const is 2 more letters to type.

if “let” was “letitbe” I bet const would be more popular

seriously though, I wish they could have chosen a 3-letter word for const in
keeping with var and let. I know const exists in other languages, but it
doesn’t even mean the exact same thing as some other languages anyway.

~~~
dpwm
> I wish they could have chosen a 3-letter word for const in keeping with var
> and let.

"set" or "fix" would be quite nice, given what const actually does.

~~~
DonHopkins
I'm having one of those days when variables won't and constants aren't.

