How to Deal with Errors & Warnings 2025

How to Deal with Errors & Warnings in React JS

Errors and warnings are common in any software development process, and React is no exception. React provides powerful debugging tools and a clear system for handling errors and warnings. Understanding how to identify, troubleshoot, and resolve them will make you a more effective React developer.

1. Handling Runtime Errors in React

A runtime error happens when the app is running. React throws these errors when something goes wrong while executing the code. These can often be tracked by checking the error messages in the browser console.


        // Example of a Runtime Error in React
        import React from 'react';

        const App = () => {
            const [count, setCount] = React.useState(0);

            // This will cause an error if you try to increment the counter using an undefined function.
            setCount(count + 1);  // Runtime error! This code is invalid because setCount should be called in a function.

            return 

{count}

; }; export default App;

**Solution:** Ensure that you are using state setters like `setCount` correctly, i.e., inside an event handler or a lifecycle method to avoid unexpected behavior.

2. Handling Syntax Errors

Syntax errors happen when your code violates JavaScript syntax rules. React will point out where the error occurred in the terminal or browser console. These are often the result of typos, missing brackets, or incorrect function signatures.


        // Example of a Syntax Error in React
        import React from 'react';

        const App = () => {
            return (
                

Hello World

); // Missing closing
tag here, causing a syntax error }; export default App;

**Solution:** Always check for missing or mismatched closing tags or braces. Modern editors like VSCode will highlight mismatched syntax to make debugging easier.

3. Warning: Uncontrolled Components

React has a concept of controlled and uncontrolled components. Uncontrolled components refer to inputs or form elements where the React component doesn't manage the state of the input directly.


        // Example of Uncontrolled Component Warning
        import React, { useRef } from 'react';

        const Form = () => {
            const inputRef = useRef();  // Using useRef without controlling the input value

            const handleSubmit = (event) => {
                event.preventDefault();
                alert(inputRef.current.value);  // Accessing value directly
            };

            return (
                
); }; export default Form;

**Solution:** If you are managing form state directly through React (using controlled components), you should always bind the input value to a state variable. This ensures React is aware of the input value at all times.

4. Warning: Missing `key` Prop in List Rendering

React requires that each child in a list of elements has a unique `key` prop. If you don’t provide a `key`, React will show a warning in the console.


        // Example of Missing Key Prop Warning
        import React from 'react';

        const List = () => {
            const items = ['Apple', 'Banana', 'Cherry'];

            return (
                
    {items.map((item) => (
  • {item}
  • // Missing key prop here! ))}
); }; export default List;

**Solution:** Always add a `key` prop when rendering lists in React to help React efficiently update and render elements.


        // Corrected Code with Key Prop
        const List = () => {
            const items = ['Apple', 'Banana', 'Cherry'];

            return (
                
    {items.map((item, index) => (
  • {item}
  • // Now each item has a unique key! ))}
); };

5. How to Handle Errors in Lifecycle Methods

React lifecycle methods like `componentDidMount` or `useEffect` can often encounter errors when interacting with APIs, external services, or asynchronous operations.


        // Example of Handling Errors in useEffect
        import React, { useState, useEffect } from 'react';

        const FetchData = () => {
            const [data, setData] = useState(null);
            const [error, setError] = useState(null);

            useEffect(() => {
                fetch('https://api.example.com/data')
                    .then((response) => response.json())
                    .then((data) => setData(data))
                    .catch((error) => setError(error.message));  // Handling error
            }, []);

            if (error) {
                return 
Error: {error}
; } if (!data) { return
Loading...
; } return
Data: {JSON.stringify(data)}
; }; export default FetchData;

**Solution:** Always use `try-catch` blocks or `.catch` with promises to handle any asynchronous errors that may occur during API calls or other side effects.

6. Using Error Boundaries to Catch JavaScript Errors

React provides **Error Boundaries** to catch JavaScript errors in any part of the component tree and display a fallback UI instead of crashing the entire component tree.


        // Example of Error Boundary in React
        import React, { Component } from 'react';

        class ErrorBoundary extends Component {
            constructor(props) {
                super(props);
                this.state = { hasError: false, error: null };
            }

            static getDerivedStateFromError(error) {
                return { hasError: true, error: error };
            }

            componentDidCatch(error, info) {
                console.log(error, info);
            }

            render() {
                if (this.state.hasError) {
                    return 

Something went wrong: {this.state.error.message}

; } return this.props.children; } } export default ErrorBoundary;

**Solution:** Wrap your components inside an **Error Boundary** to catch and handle errors gracefully in production.

Conclusion

React provides helpful tools and patterns for debugging errors and warnings in your application. Always check the browser console for helpful messages that guide you to fix issues. Use error boundaries to catch unexpected errors, and remember to handle asynchronous operations carefully using `try-catch` or `.catch` to avoid runtime crashes. By staying proactive about error handling, you can create more robust and resilient applications.