What's Actually Happening

React components fail to render when there are errors in JSX syntax, incorrect state updates, missing props, or component lifecycle issues. The component either doesn't appear on screen or shows an error boundary message.

The Error You'll See

Blank screen:

bash
// Nothing renders, page is blank
// No error in console

Error boundary:

bash
Error: Something went wrong.
Error: Minified React error #323

Console error:

bash
Warning: Each child in a list should have a unique "key" prop.
Uncaught Error: Component is not defined
TypeError: Cannot read properties of undefined

Why This Happens

  1. 1.JSX syntax error - Incorrect HTML structure
  2. 2.Missing return - Component doesn't return JSX
  3. 3.Wrong state update - Mutating state directly
  4. 4.Missing key prop - List items without keys
  5. 5.Null/undefined props - Accessing properties on null
  6. 6.Wrong import - Component not imported correctly

Step 1: Check Component Returns JSX

```jsx // WRONG: Component doesn't return anything function MyComponent() { const data = "Hello"; // Missing return! }

// CORRECT: Component returns JSX function MyComponent() { const data = "Hello"; return <div>{data}</div>; }

// WRONG: Not returning in arrow function const MyComponent = () => { <div>Hello</div> // Implicit return needs parentheses }

// CORRECT: Use parentheses for implicit return const MyComponent = () => ( <div>Hello</div> )

// Or explicit return const MyComponent = () => { return <div>Hello</div>; } ```

Step 2: Check JSX Syntax

```jsx // WRONG: Unclosed tag function MyComponent() { return <div><p>Hello</div>; }

// CORRECT: Properly closed tags function MyComponent() { return <div><p>Hello</p></div>; }

// WRONG: Multiple root elements function MyComponent() { return ( <div>First</div> <div>Second</div> // Error: Adjacent JSX elements ); }

// CORRECT: Single root element function MyComponent() { return ( <> <div>First</div> <div>Second</div> </> ); }

// WRONG: Using class instead of className <div class="container"> // React uses className

// CORRECT: <div className="container"> ```

Step 3: Fix State Updates

```jsx // WRONG: Mutating state directly function Counter() { const [count, setCount] = useState(0);

const increment = () => { count = count + 1; // Don't mutate! };

return <button onClick={increment}>{count}</button>; }

// CORRECT: Use setState function function Counter() { const [count, setCount] = useState(0);

const increment = () => { setCount(count + 1); // Correct };

return <button onClick={increment}>{count}</button>; }

// For objects, spread to create new object const [user, setUser] = useState({ name: '', email: '' });

// WRONG: user.name = 'John'; // Mutation

// CORRECT: setUser({ ...user, name: 'John' }); // New object setUser(prev => ({ ...prev, name: 'John' })); // Using callback ```

Step 4: Handle Null and Undefined

```jsx // WRONG: Accessing property on undefined function UserProfile({ user }) { return <div>{user.name}</div>; // Error if user is undefined }

// CORRECT: Add null check function UserProfile({ user }) { if (!user) return <div>Loading...</div>; return <div>{user.name}</div>; }

// Or use optional chaining function UserProfile({ user }) { return <div>{user?.name}</div>; }

// Or provide default value function UserProfile({ user = {} }) { return <div>{user.name}</div>; }

// Or use && for conditional rendering function UserProfile({ user }) { return ( <div> {user && <span>{user.name}</span>} </div> ); } ```

Step 5: Add Unique Keys for Lists

```jsx // WRONG: Missing key prop function UserList({ users }) { return ( <ul> {users.map(user => ( <li>{user.name}</li> // Warning: Missing key ))} </ul> ); }

// CORRECT: Add unique key function UserList({ users }) { return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }

// WRONG: Using index as key (anti-pattern) {items.map((item, index) => ( <li key={index}>{item.name}</li> // Use only if no stable ID ))}

// CORRECT: Use stable unique ID {items.map(item => ( <li key={item.id}>{item.name}</li> ))}

// For nested lists, use combination {categories.map(category => ( <div key={category.id}> {category.items.map(item => ( <span key={${category.id}-${item.id}}>{item.name}</span> ))} </div> ))} ```

Step 6: Fix Component Imports

```jsx // WRONG: Wrong import path import MyComponent from './MyComponent'; // File is MyComponent.jsx?

// Check file extension and path // MyComponent.jsx, MyComponent.js, index.jsx in MyComponent/

// WRONG: Default import for named export // In component file: export const MyComponent = () => <div>Hello</div>;

// Import: import MyComponent from './MyComponent'; // Wrong!

// CORRECT: Named import for named export import { MyComponent } from './MyComponent';

// Or change to default export: export default function MyComponent() { return <div>Hello</div>; }

// Then use default import: import MyComponent from './MyComponent'; ```

Step 7: Check useEffect Dependencies

```jsx // WRONG: Infinite render loop function DataFetcher() { const [data, setData] = useState([]);

useEffect(() => { fetchData().then(setData); }); // Missing dependency array = runs every render

return <div>{data.length}</div>; }

// CORRECT: Add empty dependency for mount only useEffect(() => { fetchData().then(setData); }, []); // Run once on mount

// WRONG: Stale closure function Counter() { const [count, setCount] = useState(0);

useEffect(() => { const interval = setInterval(() => { console.log(count); // Always logs 0 }, 1000); return () => clearInterval(interval); }, []); // count not in dependencies }

// CORRECT: Include dependencies useEffect(() => { const interval = setInterval(() => { console.log(count); }, 1000); return () => clearInterval(interval); }, [count]); // count in dependencies ```

Step 8: Debug with React DevTools

```jsx // Install React Developer Tools browser extension

// Check component tree // 1. Open DevTools (F12) // 2. Go to React tab (Components) // 3. Select component to inspect props and state

// Common debugging patterns: function MyComponent({ data }) { console.log('MyComponent rendered', data);

// Log state changes useEffect(() => { console.log('Data changed:', data); }, [data]);

// Use debugger if (!data) { debugger; // Pauses execution }

return <div>{data}</div>; }

// React.StrictMode causes double render in dev // This is intentional for finding issues <React.StrictMode> <App /> </React.StrictMode> ```

Step 9: Check Conditional Rendering

```jsx // WRONG: Falsy value renders 0 function Cart({ items }) { return ( <div> {items.length && <CartList items={items} />} </div> ); } // If items.length is 0, renders "0" on screen

// CORRECT: Use explicit boolean function Cart({ items }) { return ( <div> {items.length > 0 && <CartList items={items} />} </div> ); }

// Or ternary for fallback function Cart({ items }) { return ( <div> {items.length > 0 ? ( <CartList items={items} /> ) : ( <p>Cart is empty</p> )} </div> ); }

// Or use double negation {!!items.length && <CartList items={items} />} ```

Step 10: Check Context and Provider

```jsx // WRONG: Using context without provider const ThemeContext = createContext('light');

function App() { return <Button />; // No ThemeProvider }

function Button() { const theme = useContext(ThemeContext); return <button className={theme}>Click</button>; }

// CORRECT: Wrap with provider function App() { return ( <ThemeContext.Provider value="dark"> <Button /> </ThemeContext.Provider> ); }

// Check provider value function App() { const [theme, setTheme] = useState('light');

return ( <ThemeContext.Provider value={{ theme, setTheme }}> <Button /> </ThemeContext.Provider> ); }

// Consumer side: function Button() { const { theme } = useContext(ThemeContext); return <button className={theme}>Click</button>; } ```

React Rendering Issues Checklist

IssueSymptomFix
No returnBlankAdd return statement
State mutationNo updateUse setState
Missing keyWarningAdd unique key
Null propErrorAdd null check
Wrong importUndefinedCheck import path
Missing depsStale dataAdd to useEffect

Verify the Fix

```jsx // After fixing component issues

// 1. Check console for errors // Should be no red errors

// 2. Use React DevTools // Component should appear in tree

// 3. Check props and state in DevTools // Values should be as expected

// 4. Test user interactions // State updates should reflect in UI

// 5. Verify all conditions // Edge cases should handle gracefully

// 6. Check performance // No unnecessary re-renders ```

  • [Fix React useState Not Updating](/articles/fix-react-usestate-not-updating)
  • [Fix React useEffect Infinite Loop](/articles/fix-react-useeffect-infinite-loop)
  • [Fix React Props Undefined](/articles/fix-react-props-undefined)