DEV Community

John Au-Yeung
John Au-Yeung

Posted on • Originally published at thewebdev.info

React Antipatterns to Avoid

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 some React antipatterns that we should avoid.

bind() and Functions in Components

When we call bind in React class components, we shouldn’t call them repeatedly in our props. Instead, we should call bind in the constructor so that we don’t have to call bind on the fly when we pass in our class component methods as props.

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

import React from "react";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    };
    this.updateValue = this.updateValue.bind(this);
  }
  updateValue(e) {
    this.setState({
      name: e.target.value
    });
  }
  render() {
    return (
      <>
        <form>
          <input onChange={this.updateValue} value={this.state.name} />
        </form>
        <p>{this.state.name}</p>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we have an input which calls the updateValue method when the input value is changed.

We have:

this.updateValue = this.updateValue.bind(this);
Enter fullscreen mode Exit fullscreen mode

in the constructor so that it’ll always bind the component as the value of this .

Now we don’t have to do it again repeatedly everywhere. Also, we won’t be creating a new function every time the onChange event is emitted since we didn’t call bind , which returns a new function.

The performance hit from creating methods on the fly when our app grows large is going to be noticeable in some situations.

So instead of writing:

<input onChange={this.updateValue.bind(this)} value={this.state.name} />
Enter fullscreen mode Exit fullscreen mode

we write what we have above.

Missing key Prop or Using indexes in key Prop

The key prop is important when we render lists, even though it may seem like it’s doing nothing sometimes. The unique key prop value lets React identify list items correctly.

key prop values are used to match the children in the original tree with the children in the subsequent tree.

Therefore, using the array’s index is also bad because it may lead React to render the wrong data.

It’s best to use unique IDs as the value of the key prop. We can create an array with unique IDs that we can use as keys as follows:

import React from "react";
import { v4 as uuidv4 } from "uuid";

const arr = [
  {
    fruit: "apple",
    id: uuidv4()
  },
  {
    fruit: "orange",
    id: uuidv4()
  },
  {
    fruit: "grape",
    id: uuidv4()
  }
];

export default function App() {
  return (
    <div className="App">
      {arr.map(a => (
        <p key={arr.id}>{a.fruit}</p>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we used the uuid package to create a unique UUID to use as the value of the key prop. This way, there’s almost no chance of collision of unique IDs.

This way, IDs are unique and predictable, and we don’t have to think of a way to generate the unique ID for each item ourselves.

Components Name

Component names have to begin with a capital letter. For instance, if we write the following code, we’ll get an error from React:

import React from "react";

const foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <foo />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

If we run the code above, React will give us the error ‘ is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.’

Therefore, we should instead name our components always with a capital letter to start:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Then we’ll see ‘foo’ displayed on the screen as we expected.

Photo by chatnarin pramnapan on Unsplash

Close Every Element

All component tags have to have a closing tag or a slash in the end for self-closing components. For instance, if we have:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

We’ll get a syntax error because we’re missing a closing slash or tag in:

<Foo>
Enter fullscreen mode Exit fullscreen mode

To make the app run, we write instead:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  return (
    <div className="App">
      <Foo />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

<Foo></Foo> also works.

Conclusion

It’s easy to make mistakes when we’re writing React components. We have to remember to capitalize the first letter of component names. Also, we have to close the tags of the component or add a closing slash for self-closing components.

Also, we should call bind first so that we don’t have to call it repeatedly to bind to the right value of this in class-based components.

Top comments (2)

Collapse
 
pengeszikra profile image
Peter Vivo

If you use functional react component with arrow functions instead class then you never face any bind problem.

Collapse
 
aumayeung profile image
John Au-Yeung

Yes. Function components avoid any use of this so you won't have to worry about bind.

And arrow functions is even cleaner.