I've been running a 3-4 day course covering fundamental JavaScript and React. The first day or so is focused on JavaScript fundamentals and new features of ES2015.
- let, var, const
- destructuring
- functions, arrow functions, scope, context
- arrays / array methods - map, filter, reduce
Basically, the material covered in JavaScript - The React Parts
Then I move into React, starting with functional components
- components / jsx
- props
- destructuring props
- children
- etc
When it gets to managing state / events - currently switch to using Classes.
I'm finding that this jump feels a little akward. All of the content / ideas that have been reinforced for most of the course at this point is really
- Focus on JSON, and functions that operate / transform data
- Transforming data to components
- Pure functions
- You don't need a class for everything
- Getting people used to functional programming, and the dynamic nature of JavaScript as most of the current students are .NET/C# devs that don't do much JavaScript.
Instead of having a nice logical progression of concepts - it's a big context shift - just to manage an onChange event / state for an input field grows into
- ES2015 classes
- Extending from React.component
- Explaining the constructor, and the logic that should go there
- Context of
thisand the gotcha's - LifeCycle methods
Even if just focusing on the basics of - constructor, render and not the full LifeCycle - it tends to lead to divergent conversation about that.
Then - after going through Classes, and teaching Hooks - "oh, all that annoying stuff I just showed you for simply managing the input of a field? that can be cut down to X".
For new people to React, that haven't used it much before - or it's their first time, is there value in showing them the "hard way" before the hooks? It would be one thing if hooks was a 3rd party library - but it's part of core React now.
For example, if the class is used to a component like:
let SomeComponent = () => {
return (
<select>
{ /* .... options */ }
</select>
}Introducing State, and say to drive a cascading dropdown where the option in the first select drives the values in the second
let SomeComponent = ({ items1, items2 }) => {
let [select1, setSelect1] = useState();
return (
<>
<select value={select1} onChange={evt => setSelect1(evt.target.value)}>
{/* .... options */}
</select>
<select>
{items2
.filter(() => { /* filter logic */ })
.map(() => { /* spit out option tags */})}
</select>
</>
);
};(yeah yeah - should create a SelectList and reuse it - but thats not the point here)
But since people are used to functions, destructuring, array methods, destructuring assignment from functions - this logically builds off of the other material that I have covered.
I introduce:
- importing useState - the value, and the setter for it
- explaining the ordering of the returned results
- binding an event to set the value
There is more to know about hooks than that - but there is a logical way to expand on those
If going to classes -
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedItem: undefined
};
}
setValue(evt) {
this.setState({});
}
render() {
return (
<>
<select
value={select1}
onChange={evt => this.setValue(evt.target.value)}
>
{/* .... options */}
</select>
<select>
{items2
.filter(() => {
/* filter logic */
})
.map(() => {
/* spit out option tags */
})}
</select>
</>
);
}
}The number of new concepts introduced here for what should be a simple addition blows up quickly
- this.state
- this.setState
- outside of the constructor - don't directly set state
- using setState - object vs state setter and when to use which one and why
- how you approach defining methods, and ensuring
thisis bound properly- normal class methods, and
this.method = this.method.bind(this) - or class props with
method = () => { /* .... */ } - or in the render when invoking the method, using an arrow function there
onChange={(evt)=this.stuff()}
- normal class methods, and
Even if I was to only show one approach and be consistent with how I teach it - people are going to try the various other ways also.
I do think that understanding class components, and the rendering lifecycle is important - and wouldn't say 'don't teach classes at all'.
One of the arguments I've heard for not teaching hooks, or teaching hooks last is
- They are a new feature, best pratices / etc around them are not well understood yet
- People are more likely to be exposed to React code using React.Component and not hooks - so being able to work with those, and understanding how they work is important.
I see those as reasons to why you should still cover React.Component - but I don't think that's a good reason to teach that before classes.