Learning React Hooks: Part 2: Component-like Functions

Learning React Hooks

React hooks provide functionality to “hook into” React properties and life-cycle values outside of component classes.


Component-like Functions

In the previous part, the state of a component was examined as setup during the Mounting phase and then changed during the Updating phase. This was done, initially, using the constructor() function of a class and then as a result of any calls to setState() to change its values during events such as a user clicking.

Component classes, however, are often “heavy” and a need for a smaller and more “light-weight” solution using only a few lines of code is sometimes needed for repetitive tasks. Enter component-like functions.

Consider the following code:

import React, {Component} from 'react';

function Example(props) {
  return (
    <p>Show the example value: {props.exampleValue}</p>
  );
}

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      example: 1,
      secondExample: 2
    };

  }

  render() {
    return(
      <div>
        <Example exampleValue={this.state.example} />
      </div>
    );
  }
}

export default App;

Functions can be treated as if they were class components through naming them and passing them props. Instead of needing to write an entire class, a function can return values arranged with any elements.

Functions can also be an easy and more efficient way to write code whose only task is to “render” some result. Instead of needing an additional class, the function can take the values and show them.

Lifting State

Like classes being passed properties, it is also possible to write a function that calls “up” to a parent component that follows the same structure outlined in the previous part.

Consider the following updated form of the “lifting state” example:

import React, {Component} from 'react';

function Example(props) {
  return (
    <p 
      onClick={() => props.increaseValue()}>
        Show the example value: {props.exampleValue}
    </p>
  );
}

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      example: 1,
      secondExample: 2
    };

  }

  increaseValue = () => {
    this.setState({example: this.state.example + 1});
  }

  render() {
    return(
      <div>
        <Example 
          exampleValue={this.state.example} 
          increaseValue={this.increaseValue} 
        />
      </div>
    );
  }
}

export default App;

In the above code, the “size” of the now function Example has been reduced to only its return statement. However, it works the same! Any click on its text will call “up” to the parent component App and to the function increaseValue() that will trigger setState() and ultimately lead to the re-rendering of the content within the Example function.

Functions Don’t Have State

Normally, functions don’t have their own state. They can be called and passed values, but they cannot normally react to changes on their own. This makes them very useful for generating many smaller elements such as items in a list with their own event listeners, but not as useful for making potentially smaller component-like code blocks that could keep track of its own data over time.