Confused: What I learnt in Javascript doesn't translate to React

Tell us what’s happening:
I’m struggling to understand React.

I’ve done the HTML/CSS and Javascript courses, and I’m comfortable with those. I was hoping the next course would finally explain how Javascript can be used to interact with HTML/CSS to build something real. Instead, we’re introduced to libraries where Javascript isn’t directly used. Instead, we’re using SASS or React, and while these ultimately translate to Javascript, they don’t work exactly like Javascript. As an analogy, Javascript is like American English, and now I suddenly have to speak Cockney English. It’s still English, but it’s totally weird and unfamiliar.

The syntax I’ve learnt in Javascript, like calling functions, declaring functions, declaring variables etc doesn’t translate into React. Take this function from the exercise for example:

shouldComponentUpdate(nextProps, nextState)

If I were to read this as pure Javascript, it would look like a function is being declared, except without the word “function” before the name of the function. If it’s not declaring a new function, and in this case an existing built-in function is being invoked, then in normal Javascript, the function would be called like so:

      nameOfFunction(enter whatever arguments); 

But that’s not what shouldComponentUpdate(nextProps, nextState) looks like! It’s not even a function that takes in a function as an argument, like map() or reduce(). It’s a function that somebody else already created that you can modify on the inside??

Never mind that. HOW is it taking in the arguments nextProps and nextState? What is actually passing in the argument for nextProps? The argument gets passed when the element is declared in JSX, I suppose, then we have to set the attribute value={this.state.value}. Fine. So what is nextProps exactly? Is it a number? An object? Why do i have to extract the number value by typing “nextProps.value”? Because “this.state.value” is a number. “Value” is a reference to that number. “nextProps” is a reference to “value”. So why isn’t “nextProps” on its own referring to the number?

For the OnlyEvens class, inside the render() method, why is the ‘this’ in “this.props.value” needed when ‘this’ is not needed for nextProps.value inside shouldComponentUpdate()?

We’re not even using the argument ‘nextState’ for anything. So is it just being ignored?

Is there a lesson or series of exercises on FreeCodeCamp that allows us to use javascript directly on HTML instead of React? Because I feel like there’s a missing link. I need to see how Javascript interacts with HTML/CSS directly before I move into React, which seems to be doing a lot ‘under the hood’ which I cannot see nor understand.

Your code so far


class OnlyEvens extends React.Component {
  constructor(props) {
    super(props);
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
     // change code below this line
     console.log(this.props.value);
     if (nextProps.value % 2 ==0){
       return true;
     }
    else {
      return false;
    }
     // change code above this line
  }
  componentWillReceiveProps(nextProps) {
    console.log('Receiving new props...');
  }
  componentDidUpdate() {
    console.log('Component re-rendered.');
  }
  render() {
    return <h1>{this.props.value}</h1>
  }
};

class Controller extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
    this.addValue = this.addValue.bind(this);
  }
  addValue() {
    this.setState({
      value: this.state.value + 1
    });
  }
  render() {
    return (
      <div>
        <button onClick={this.addValue}>Add</button>
        <OnlyEvens value={this.state.value}/>
      </div>
    );
  }
};

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36.

Link to the challenge:

1 Like

Ah, but you’re not declaring functions in isolation. Here, you’re working on an ES6 class, which is a slightly different thing. It might look more like:

class Person{
  constructor(name, age, friends){
    this.name = name;
    this.age = age;
    this.friends = friends;
  }
  // this is a function, yes - but it's defined on the class itself!
  sayName(){
    return `Hello, my name is ${this.name}!`;
  }
  shoutName(){
    return this.sayName().toUpperCase();
  }
}

so notice, I didn’t have to use function for those, or const or let or whatever. They are being defined within that class, so they are actually being attached to the prototype of my object when I use the new Person() to define my object.

If you aren’t familiar with the class syntax, take a look at https://devdocs.io/javascript/classes

1 Like

If you want to use vanilla Javascript instead of using React and other frameworks, you should read about DOM manipulation.

2 Likes

That’s because it’s ES6 (a 2015 iteration of the JavaScript language available for modern browsers since, well, 2015/6).

The concrete feature is method shorthand for syntactic sugar classes (it means they’re not real classes but rather a way of easily declare prototypical inheritance with the class keyword.

In ES5< you’d normally declare a method to a “class” like this:

function MyClass(prop) {
  this.prop = prop
}

MyClass.prototype.method = function(params) {
  // method body
}

And it translates to ES6 as:

class MyClass {
  constructor(prop) {
    this.prop = prop
  }

  method(params) {
    // method body
  }
}

ES6 classes also support getters and super(), and newer versions of JS have property declaration but it has to be transpiled using babel and a certain plugin so that you don’t need to use a constructor or a method to declare your React’s initial state as stated here: https://daveceddia.com/where-initialize-state-react/ .

2 Likes