React Tips — Force Render, Conditionals, Listen for Navigation

John Au-Yeung - Oct 4 '20 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

How to Force a Function Component to Render

We can force a function component to render with the use-force-update package.

To install it, we run:

npm install use-force-update

or:

yarn add use-force-update

Then we can use it by writing:

import useForceUpdate from 'use-force-update';

const App = () => {
  const forceUpdate = useForceUpdate();

  const rerender = () => {
    console('rerendering');
    forceUpdate();
  };

  return <button onClick={rerender} />;
};

We get the useForceUpdate hook to return the forceUpdate function that lets us update whenever we want.

Also, we can set a state to make a React component update.

For instance, we can write:

import React, { useState } from 'react';

function useForceUpdate(){
  const [value, setValue] = useState(0);
  return () => setValue(value => ++value);
}

function App() {
  const forceUpdate = useForceUpdate();

  return (
    <div>
      <button onClick={forceUpdate}>
        re-render
      </button>
    </div>
  );
}

We created our own useForceUpdate hook to update a value state.

The useState hook returns a state variable and a function to update it.

Whenever we update a state, React will render the component again.

componentDidMount Equivalent in a React Function Component

The equivalent of componentDidMount in a function component is the useEffect hook with an empty array.

For instance, we can write:

useEffect(() => {
  //...
}, []);

to make the code in the callback only load when the component mounts.

We can also pass in variables to the array to watch those values for changes:

useEffect(() => {
  //...
}, [foo, bar]);

The content can be any value like states, props, etc.

Detect Route Change with React Router

We can detect route change with React Router with the history.listen method.

For instance, we can write:

history.listen((location, action) => {
  console.log(location, action);
})

location is the native location object that has all the URL data like the pathname for the pathname.

search for the query string.

hash for the string after the hash.

action has the name for the navigation action.

Setting State on componentDidMount()

Setting state in the componentDidMount method isn’t an antipattern.

It’s a recommended practice for setting state when the component mounts.

For instance, we can use it to get API data and set the state:

componentDidMount() {
  fetch("https://randomuser.me/api")
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
          isLoaded: true,
          user: results[0]
        });
      },
      (error) => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    )
}

We get the data from an API with the fetch API.

Then we get the resulting data in the first then callback to set the state for the data.

In the 2nd callback, we set the isLoaded state to false and an error state.

Use if…else… Statement in React render Function

There are a few ways to display things conditionally with React.

We can use various boolean expressions to do so.

For example, we can write:

render() {
  const { isLoggedIn } = this.state;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleClick} />
      ) : (
        <LoginButton onClick={this.handleClick} />
      )}
    </div>
  );
}

We get the isLoggedIn state and use that to check the if the user is logged in.

If the user isn’t then we return LogoutButton .

Otherwise, we return LoginButton .

We can also use an if-else statement to assign a component to a variable/

For instance, we can write:

render() {
  let button;
  if (isLoggedIn) {
    button = <LogoutButton onClick={this.handleClick} />;
  } else {
    button = <LoginButton onClick={this.handleClick} />;
  }

  return (
    <div>
      {button}
    </div>
  );
}

We check isLoggedIn with an if-else statement instead of a ternary expression.

We assigned our components to the button variable and render that instead of writing everything inline.

This lets us write longer expressions in a conditional statement.

Also, we can use the && operator to display things given a condition.

For example, we can write:

render() {
  return (
    <div>
      {cartItems.length > 0 &&
        <h2>
          You have {cartItems.length} in the cart.
        </h2>
      }
    </div>
  );
}

If cartItems.length > 0 is true then the stuff that comes after it is rendered.

Conclusion

We can force a component to render in various ways.

Also, we can display things conditionally with several kinds of statements and expressions.

And we can use history.listen to listen for changes in React Router.

The post React Tips — Force Render, Conditionals, Listen for Navigation appeared first on The Web Dev.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .