Handling events and callbacks in ReactJS

Leave a comment

https://facebook.github.io/react/docs/thinking-in-react.html

So I have been studying ReactJS that last couple weeks. Mostly banging my head trying to come up with simple examples. Here is one based on Thinking in React that demos how to do callbacks.

Starting simple

Here is a simple bit of code that counts words.

Screen Shot 2017-09-01 at 8.44.25 AM.png

Note the main component is called ‘WordCount’, and it does a fine job of counting words.

Adding composition and parent callbacks

But what I want to do is create a sub-component, maintain the state in the parent component, and have the parent component pass it’s callback down to the subcomponent so it can be called back.

Here is what I got working.

Screen Shot 2017-09-01 at 8.47.15 AM.png

Note the following.

  1. Child calls parent callback

I don’t know if this is common, or even necessary, but based on the Thinking in React example this is what they do.

You define your parent callback like so

Screen Shot 2017-09-01 at 8.49.31 AM.png

And then you pass it to your child like so:

Screen Shot 2017-09-01 at 8.50.04 AM.png

Note the name pattern. ‘onSomething’ ‘handleSomething’. This I have seen in many examples and this seems common.

But then in the child you define another similar callback, and have it do nothing more than prep the data and call the parent.

Screen Shot 2017-09-01 at 8.51.20 AM.png

I don’t know what you would do this. I guess if you wanted to do some more processing (you know the saying about always adding another layer of indirection).

And then you use this child callback locally which in turn calls the parent callback we just defined.

Screen Shot 2017-09-01 at 8.53.06 AM.png

This works. I am just not sure if it’s right or needed.

What I would have expected to be able to do, is just pass the parent callback directly to the child component itself.

But I haven’t been able to figure out how to do that yet. Stay tuned…

Advertisements

How to pass anonymous arrow functions ReactJS

Leave a comment

You define the callback like this

Screen Shot 2017-08-31 at 8.31.52 AM.png

You pass it using the arrow functions like this

Screen Shot 2017-08-31 at 8.32.28 AM.png

You set it’s parameter values like this:

Screen Shot 2017-08-31 at 8.35.38 AM.png

You pass it to other components and functions like this

Screen Shot 2017-08-31 at 8.33.10 AM.png

And you add it to your controls like this

Screen Shot 2017-08-31 at 8.33.43 AM.png

ReactJS example using callback with User

Leave a comment

https://medium.freecodecamp.org/why-arrow-functions-and-bind-in-reacts-render-are-problematic-f1c08b060e36

Here is a simple example that showing the plumbing for a ReactJS app using a callback.

Screen Shot 2017-08-30 at 10.10.22 AM.png

import React from 'react';
import { render } from 'react-dom';

class User extends React.PureComponent {
  render() {
    const {name, onDeleteClick } = this.props
    console.log(`${name} just rendered`);
    return (
      <li>             
        <input 
          type="button" 
          value="Delete" 
          onClick={onDeleteClick} 
        /> 
        {name}
      </li>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [
        { id: 1, name: 'Cory' }, 
        { id: 2, name: 'Meg' }, 
        { id: 3, name: 'Bob' }
      ]
    };
  }
  
  deleteUser = id => {
    this.setState(prevState => {
      return { 
        users: prevState.users.filter( user => user.id !== id)
      }
    })
  }

  render() {
    return (
      <div>
        <h1>Users</h1>
        <ul>
        { 
          this.state.users.map( user => {
            return <User 
              key={user.id} 
              name={user.name} 
              onDeleteClick={() => this.deleteUser(user.id)} />
          })
        }
        </ul>
      </div>
    );
  }
}

export default App;

render(<App />, document.getElementById('root'));

JavaScript Arrow functions

Leave a comment

These are functionally equivalent

Screen Shot 2017-08-29 at 6.39.46 AM.png

Screen Shot 2017-08-29 at 6.39.51 AM.png

Note the difference: In arrow functions the stuff put in the () are the method arguments and the stuff that comes after ({ // }) is the return statement. That’s it.

The first method uses the new JavaScript arrow function. And it was created to do two things.

  1. Shorter functions.
  2. The non-binding of this.

Shorter functions

Normally in JS you pass functions as parameters using a function expression. Something that looks like this on i.e. Array.prototype.map() (which returns a new array with the results of calling the provide method on every element in the calling array).

Screen Shot 2017-08-29 at 6.45.19 AM.png

This is called a function expression and it’s how you can define functions that can be passed as arguments to methods.

ES2015 defined a shorter way of doing this. Something called arrow functions.

Screen Shot 2017-08-29 at 6.50.09 AM.png

With arrow functions, instead of defining everything with the keyword function, you can just create a lambda like expression like this.

Screen Shot 2017-08-29 at 6.51.09 AM.png

The way to read this is (parameters) => { // code }

i.e. you declare the parameters you need passed in in the () and then you use them in your code. This leads to some nicer more terse code.

No binding of this

Until arrow functions, every new function define its own ‘this’ value. This proved to be annoying in OO style programming.

Screen Shot 2017-08-29 at 6.59.24 AM.png

In ECMAScript 3/5, this issue was fixable by assigning another value to ‘this’ that could be closed over.

Screen Shot 2017-08-29 at 7.01.30 AM.png

Alternatively, a bound function could be created so that a preassigned ‘this’ value would be passed to the bound target function.

An arrow function does not create its own ‘this’, the ‘this’ value of the enclosing execution context is used instead. Thus the ‘this’ value in ‘setInternal’ has the same value as ‘this’ in the enclosing function.

Screen Shot 2017-08-29 at 7.18.16 AM.png

No binding of arguments

Arrow functions do not bind an arguments object. Thus, in this example, arguments is simple a reference to the same name in the enclosing scope.

Screen Shot 2017-08-29 at 7.24.00 AM.png

Here we define a variable 42, create a method out of it using () => arrow function, and then execute the method.

Screen Shot 2017-08-29 at 7.25.03 AM.png

Here we define a function foo(), define a variable method f (using the args rest parameters) and then simply return the first argument.

Arrow functions used as methods

As mentioned previously, arrow functions should not be used as methods, but rather only passed as non-method functions. Here’s what happens when used as method.

Screen Shot 2017-08-29 at 7.28.01 AM.png

Because the method ‘b’ does not bind ‘this’, ‘this’ is undefined.

You also can’t use arrow functions as constructors or access their prototype property.

Screen Shot 2017-08-29 at 7.29.52 AM.png

Misc

These are functionally equivalent.

Screen Shot 2017-08-31 at 6.10.14 AM.png

Arrow functions for beginners

Screen Shot 2017-08-31 at 7.21.13 AM.png

Screen Shot 2017-08-31 at 7.21.45 AM.png

Screen Shot 2017-08-31 at 7.21.51 AM.png

Screen Shot 2017-08-31 at 7.21.58 AM.png

Screen Shot 2017-08-31 at 7.22.05 AM.png

Screen Shot 2017-08-31 at 7.22.12 AM.png

Screen Shot 2017-08-31 at 7.22.25 AM.png

Screen Shot 2017-08-31 at 7.23.51 AM.png

Mawr…

http://wesbos.com/arrow-functions/

Screen Shot 2017-08-31 at 7.28.33 AM

Screen Shot 2017-08-31 at 7.28.48 AM

Screen Shot 2017-08-31 at 7.29.10 AM

Screen Shot 2017-08-31 at 7.29.43 AM

Screen Shot 2017-08-31 at 7.30.14 AM

Screen Shot 2017-08-31 at 7.31.33 AM

Screen Shot 2017-08-31 at 7.26.21 AM.png

Links that help
Arrow functions
Function expression
Function.prototype.bind
Arrow functions for beginners

ReactJS state callback example

Leave a comment

Here is an example simple ReactJS example that includes state and a callback.

Screen Shot 2017-08-29 at 5.58.48 AM.png

The constructor
The constructor is where we setup our component state as well as bind any functions we want to pass later to proper context.

Screen Shot 2017-08-29 at 6.00.48 AM.png

Binding

Screen Shot 2017-08-29 at 6.02.16 AM.png

You can read more about binding options and react here.

Passing functions

The next thing that’s important is to look at how you pass bounded function to your component.

Screen Shot 2017-08-29 at 6.04.55 AM.png

The commented out line is the wrong way to do it. When passing functions in react don’t include the () as that will invoke the function instead of passing it. Super common mistake. If you see an error message looking something like this:

Screen Shot 2017-08-29 at 6.06.25 AM.png

Warning: setState(...): Cannot update during an existing state transition

you’ll know you’ve got that problem.

Arrow methods

And the final thing to note is the use of the arrow function for invoking the passed in method.

Screen Shot 2017-08-29 at 6.09.28 AM.png

Arrow function as a shorter syntax than function expression and does not bind its own this. Best used as non method functions.

Links that help
https://facebook.github.io/react/docs/state-and-lifecycle.html

ReactJS example setting state

Leave a comment

Screen Shot 2017-08-28 at 4.40.25 PM.png

import React, { Component } from 'react';

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
  }
}

class App extends Component {
  render() {
    return (
      <Clock />
    );
  }
}

export default App;

How to setState ReactJS

Leave a comment

Here is an example of how to setState in ReactJS

Screen Shot 2017-08-25 at 10.21.50 AM.png

import React, { Component } from 'react';

class Counter extends Component {

    constructor(props) {
        super(props);

        this.state = {
            count : 1
        };

        this.delta = this.delta.bind(this);
    }

    delta() {
        this.setState({ count : this.state.count + 1});
    }

    render() {
      console.log('rendering...');
        return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button></div>
);
    }
}

export default Counter;

Screen Shot 2017-08-25 at 10.28.46 AM.png

Note the key is this line right here:

Screen Shot 2017-08-25 at 10.24.11 AM.png

If you don’t set that. You will get this error:

TypeError: Cannot read property 'setState' of null

Screen Shot 2017-08-25 at 10.24.41 AM.png

Which means you have the wrong ‘this’ in your function. And you fix it by binding your function with the line of code shown above.

https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

Older Entries

%d bloggers like this: