DEV Community

Cover image for 5 Critical Mistakes to Avoid When Starting a New React Project in 2024: A Beginner Guide🚀
Vishal Yadav
Vishal Yadav

Posted on

5 Critical Mistakes to Avoid When Starting a New React Project in 2024: A Beginner Guide🚀

Introduction:

React has revolutionized the way we build user interfaces, but with great power comes great responsibility. As we navigate the ever-evolving landscape of React development in 2024, it's crucial to stay informed about best practices and common pitfalls. In this comprehensive guide, we'll dive deep into five critical mistakes that developers often make when starting a new React project. By understanding and avoiding these errors, you'll set yourself up for success, write cleaner code, and create more efficient, maintainable React applications.

1. Relying Solely on Create React App (CRA) Without Exploring Modern Alternatives

Create React App (CRA) has been a go-to tool for quickly setting up React projects for years. While it's still a viable option, blindly reaching for CRA without considering alternatives could mean missing out on significant performance improvements and developer experience enhancements.

Why CRA might not be the best choice in 2024:

  • Slower build times compared to newer tools
  • Less flexibility in configuration without ejecting
  • Potential for outdated dependencies

Modern alternatives to consider:

  • Vite: Offers lightning-fast hot module replacement and build times
  • Next.js: Provides server-side rendering and an excellent developer experience
  • Remix: A full-stack React framework with a focus on web standards and performance

How to choose:

  • Assess your project requirements (SSR, static site generation, etc.)
  • Consider your team's familiarity with different tools
  • Evaluate the community support and ecosystem around each option

Pro tip: Try building a small project with different tools to get a feel for their workflows and performance characteristics.

2. Unnecessarily Importing React in Every File

Since React 17, the JSX transform has been updated, eliminating the need to import React in every file that uses JSX. This change might seem small, but it can have a significant impact on your codebase's cleanliness and maintainability.

Benefits of skipping unnecessary React imports:

  • Reduced boilerplate code
  • Cleaner file headers
  • Slightly improved bundle size

Before (pre-React 17):

import React from 'react';

function MyComponent() {
  return <div>Hello, World!</div>;
}
Enter fullscreen mode Exit fullscreen mode

After (React 17+):

function MyComponent() {
  return <div>Hello, World!</div>;
}
Enter fullscreen mode Exit fullscreen mode

Important note: If you're using React methods like useState or useEffect, you'll still need to import them explicitly:

import { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);
  // ...
}
Enter fullscreen mode Exit fullscreen mode

3. Sticking with PropTypes Instead of Embracing TypeScript

PropTypes have served React developers well for type checking, but as projects grow in complexity, TypeScript offers a more robust solution for ensuring type safety and improving the overall development experience.

Why TypeScript outshines PropTypes:

  • Catch errors at compile-time rather than runtime
  • Improved IDE support with better autocomplete and refactoring tools
  • Self-documenting code that's easier to understand and maintain

Let's compare PropTypes and TypeScript:

Using PropTypes:

import PropTypes from 'prop-types';

function UserProfile({ name, age, email }) {
  return (
    <div>
      <h1>{name}</h1>
      <p>Age: {age}</p>
      <p>Email: {email}</p>
    </div>
  );
}

UserProfile.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  email: PropTypes.string
};
Enter fullscreen mode Exit fullscreen mode

Using TypeScript:

interface UserProfileProps {
  name: string;
  age?: number;
  email?: string;
}

function UserProfile({ name, age, email }: UserProfileProps) {
  return (
    <div>
      <h1>{name}</h1>
      <p>Age: {age}</p>
      <p>Email: {email}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The TypeScript version not only provides better type checking but also serves as clear documentation for the component's props.

Migration tip: If you're working on an existing project, you can gradually adopt TypeScript by renaming files to .tsx and adding type annotations incrementally.

4. Using defaultProps for Default Values Instead of ES6 Destructuring

The defaultProps pattern has been widely used in React, but with the advent of functional components and ES6 features, there's a cleaner way to provide default values for your props.

Why ES6 destructuring is preferred:

  • Keeps all prop-related logic in one place
  • More intuitive and inline with modern JavaScript practices
  • Works seamlessly with both functional and class components

Let's compare the approaches:

Using defaultProps:

function Button({ text, color }) {
  return <button style={{ color }}>{text}</button>;
}

Button.defaultProps = {
  text: 'Click me',
  color: 'blue'
};
Enter fullscreen mode Exit fullscreen mode

Using ES6 destructuring:

function Button({ text = 'Click me', color = 'blue' }) {
  return <button style={{ color }}>{text}</button>;
}
Enter fullscreen mode Exit fullscreen mode

The ES6 destructuring approach is more concise and keeps all the component's prop logic together, making it easier to understand at a glance.

Advanced tip: You can combine this with TypeScript for even better prop management:

interface ButtonProps {
  text?: string;
  color?: string;
}

function Button({ text = 'Click me', color = 'blue' }: ButtonProps) {
  return <button style={{ color }}>{text}</button>;
}
Enter fullscreen mode Exit fullscreen mode

5. Opting for Class Components Over Functional Components and Hooks

While class components have been a fundamental part of React for years, functional components combined with hooks have become the preferred pattern for writing React code in 2024.

Advantages of functional components and hooks:

  • Simpler syntax and easier to read
  • Better performance in some cases due to reduced overhead
  • Easier to test and reuse logic across components
  • More aligned with modern JavaScript practices

Let's refactor a class component to a functional component with hooks:

Class Component:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  componentDidMount() {
    document.title = `Count: ${this.state.count}`;
  }

  componentDidUpdate() {
    document.title = `Count: ${this.state.count}`;
  }

  increment = () => {
    this.setState(prevState => ({ count: prevState.count + 1 }));
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Functional Component with Hooks:

import { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  const increment = () => setCount(prevCount => prevCount + 1);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The functional component version is more concise, easier to understand, and uses modern React patterns like the useState and useEffect hooks.

Bonus: Custom Hooks

One of the most powerful features of hooks is the ability to create custom hooks to encapsulate and reuse stateful logic. Here's an example of how you could extract the counter logic into a custom hook:

function useCounter(initialCount = 0) {
  const [count, setCount] = useState(initialCount);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  const increment = () => setCount(prevCount => prevCount + 1);

  return { count, increment };
}

function Counter() {
  const { count, increment } = useCounter();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

This approach allows you to reuse the counter logic across multiple components easily.

Conclusion:

As we've explored these five critical mistakes to avoid when starting a new React project in 2024, it's clear that staying updated with modern practices is crucial for writing efficient, maintainable, and enjoyable React code. By choosing the right project setup tools, embracing TypeScript, leveraging ES6 features, and adopting functional components with hooks, you'll be well-equipped to tackle the challenges of modern React development.

Remember, the React ecosystem is constantly evolving, so make it a habit to stay informed about new tools, techniques, and best practices. Experiment with different approaches, contribute to open-source projects, and engage with the React community to continually improve your skills.

By avoiding these common pitfalls and embracing modern React development practices, you'll not only write better code but also enjoy a more productive and satisfying development experience. Happy coding, and may your React projects be a testament to clean, efficient, and powerful web applications!

Top comments (13)

Collapse
 
leob profile image
leob

Excellent "no-nonsense" article - one of the best React articles I've come across on dev.to recently!

Collapse
 
kc900201 profile image
KC

Clean and precise. One suggestion for future improvement I can think of is provide a development roadmap (existing roadmap or create one from scratch) to the react beginners for a clearer description.

Consider dev.roadmap as a reference.

Collapse
 
mexikode profile image
MexiKode ⚙

Rule #1 Dont start a react project :D

Collapse
 
masudalimrancasual profile image
Masud Al Imran

To elaborate. Don't start a React Project if you can't finish the project within 6 month. Otherwise when the newer React version comes, be prepared to heavily refactor previous code.

Collapse
 
jangelodev profile image
João Angelo

Hi Vishal Yadav,
Top, very nice and helpful !
Thanks for sharing.

Collapse
 
vyan profile image
Vishal Yadav

Welcome!

Collapse
 
kpndevroot profile image
kpndevroot

nice doc.

Collapse
 
vyan profile image
Vishal Yadav

Thanks !

Collapse
 
priyanshu654 profile image
priyanshu654

useful

Collapse
 
suraj__ profile image
Suraj

Great for the React beginners 👍🏼

Collapse
 
marako profile image
Dimitris Marakomichelakis

Nice one!

Collapse
 
capgo profile image
Capgo

Awesome post!

Collapse
 
victor_ememe_1366f0eb9e52 profile image
Victor Ememe

Thanks for the tips. Really insightful 👌🏾💡