React Tips — Elements and Caching Values
Tags: react, webdev, programming, javascript
Published: 2021-01-23 19:51:56

**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 the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at various less common features that are helpful for developing React apps.

### Create React Elements with Strings

We can reference React elements with strings instead of JSX. HTML elements can be written with strings instead of JSX.

For instance, we can write the following code:

```
import React from "react";

const Component = "div";

export default function App() {
  return <Component className="App">hello</Component>;
}
```

In the code above, we have `Component` set to `'div'` , which means that `Component` is a div element. This is good because we can change the `Component` ‘s element tag dynamically without hassle.

For instance, we can make a toggle to switch between div and p as follows:

```
import React from "react";

export default function App() {
  const [Component, setComponent] = React.useState("div");
  return (
    <>
      <button
        onClick={() =>
          setComponent(Component => (Component === "div" ? "p" : "div"))
        }
      >
        Toggle Tag
      </button>
      <Component className="App">hello</Component>
    </>
  );
}
```

In the code above, we have a button to toggle the tag of `Component` between div and p.

Therefore, when we click the button, we’ll see that the tag of `Component` switches between div and p as we click the button.

### Retain Previous Values

We can use the `useRef` hook to retain the previous value of a prop or state.

For instance, we can keep the old value and the new value of a state as follows:

```
import React from "react";

export default function App() {
  const [name, setName] = React.useState("bob");
  const prevNameRef = React.useRef("");

  React.useEffect(() => {
    prevNameRef.current = name;
  }, [name]);

  const prevName = prevNameRef.current;

  return (
    <div>
      <button
        onClick={() => setName(name => (name === "bob" ? "jane" : "bob"))}
      >
        Toggle Name
      </button>
      <p>Current name:</p>
      <p>{name}</p>
      <p>Previous name:</p>
      <p>{prevName}</p>
    </div>
  );
}
```

In the code above, we have the `name` state and the `setName` function to set the value of `name` .

Then in the button, we call the `setName` function when we click it. It toggles between `'bob'` and `'jane'` .

In the `useEffect` hook, we watch the value of `name` , which sets the `prevNameRef.current` to `name` to keep the original value. Then we set `prevNameRef.current` to `prevName` so to keep things short in the `return` statement.

In the end, we’ll see the old and new values display in the returned JSX.

### Use `React.useRef` for Flexible Non-Stale Value Checks

One way to check if some data is loaded when the component loads are to use the `useRef` hook to keep track of whether the piece of data is loaded.

For instance, we can write the following code to do that:

```
import React from "react";

export default function App() {
  const [name, setName] = React.useState("");
  const loaded = React.useRef(false);

  React.useEffect(() => {
    if (!loaded.current) {
      setName("bob");
    }
    loaded.current = true;
    return () => (loaded.current = false);
  });

  return <div>{name}</div>;
}
```

In the code above, we check the `useEffect` callback that checks if `loaded.current` is `true` . If it’s not, then we call `setName` to set the `name` state’s value.

In the `useEffect` callback, we also have:

```
return () => (loaded.current = false);
```

to reset `loaded.current` to `false` when `App` unloads.

Therefore, we’ll see that the component loads with the name ‘bob’ displayed.

### Memoize Values with the useMemo Hook

We can also use the `useMemo` hook to create a memoized values, which means that it’s cached as long as it or its dependencies don’t change.

`useMemo` runs during rendering. Therefore, we shouldn’t run anything that we wouldn’t do during rendering.

It’s used as a performance optimization, but it’s not a guarantee of the integrity of the value because it might change later.

For instance, we can use it as follows:

```
import React from "react";

export default function App() {
  const [firstName, setFirstName] = React.useState("");
  const [lastName, setLastName] = React.useState("");
  const name = React.useMemo(() => `${firstName} ${lastName}`, [
    firstName,
    lastName
  ]);

  return (
    <div>
      <input value={firstName} onChange={e => setFirstName(e.target.value)} />
      <input value={lastName} onChange={e => setLastName(e.target.value)} />
      <p>{name}</p>
    </div>
  );
}
```

In the code above, we used `useMemo` to watch `firstName` and `lastName` ‘s values and then derive a new value `name` from combining the 2.

Then when we enter text into the input, we’ll see that it updates the value of `name` . However, it’ll cache the existing value if `firstName` or `lastName` don’t change.

### Conclusion

We can use the `useRef` and `useMemo` hooks to cache data. Also, we can create HTML elements with strings. This means that we can render HTML elements dynamically.