DEV Community

Cover image for "๐Ÿš€ React Quirks Explained: What You Don't Know Can Hurt You! ๐Ÿคฏ"
Raunak Sharma
Raunak Sharma

Posted on

2

"๐Ÿš€ React Quirks Explained: What You Don't Know Can Hurt You! ๐Ÿคฏ"

React is amazing, but it comes with its own set of quirks that can catch you off guard. Whether you're a beginner or an experienced developer, these surprising behaviors are a reminder of React's complexity and flexibility. Letโ€™s dive in! ๐Ÿš€

1. State Updates Are Asynchronous๐Ÿ•’

React batches state updates for better performance, which means changes to state arenโ€™t immediate.

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

const handleClick = () => {
    setCount(count + 1);
    console.log(count); // Still logs 0
};
Enter fullscreen mode Exit fullscreen mode

Why? React doesnโ€™t update the state until the end of the event loop. Use the functional form of setState to get the latest value:

setCount(prevCount => prevCount + 1);
Enter fullscreen mode Exit fullscreen mode

2. Keys Aren't Just For Performance ๐Ÿ—๏ธ

Keys help React identify elements during reconciliation. But using unstable keys, like array indices, can break your UI.

const items = ['React', 'JS', 'CSS'];
items.map((item, index) => <div key={index}>{item}</div>);
Enter fullscreen mode Exit fullscreen mode

Problem: If the array changes (e.g., sorting), React might lose track of elements. Always use unique and stable keys, like IDs.

3. useEffect Runs Twice in Strict Mode ๐ŸŒ€

Strict Mode in development deliberately calls useEffect twice to detect bugs.

useEffect(() => {
    console.log('Effect runs!');
}, []);
Enter fullscreen mode Exit fullscreen mode

Gotcha: This happens only in development. In production, useEffect runs once as expected.

4. Props Are Read-Only ๐Ÿšซ

Props are immutable in React, and modifying them directly can cause errors.

const MyComponent = ({ name }) => {
    name = 'New Name'; // โŒ Illegal
    return <h1>{name}</h1>;
};
Enter fullscreen mode Exit fullscreen mode

Solution: Use state if you need mutable data.

5. Re-renders Happen Even If Props Don't Change ๐Ÿ”

React re-renders components even if props remain the same.

const Child = ({ value }) => {
    console.log('Child renders');
    return <div>{value}</div>;
};
Enter fullscreen mode Exit fullscreen mode

Why? React doesnโ€™t automatically optimize performance. Use React.memo to prevent unnecessary re-renders:

export default React.memo(Child);
Enter fullscreen mode Exit fullscreen mode

6. Conditional Rendering Can Break Lists ๐Ÿ’ฅ

Rendering lists conditionally can lead to unpredictable outcomes.

{items.length && items.map(item => <div>{item}</div>)}
Enter fullscreen mode Exit fullscreen mode

Gotcha: If items.length is 0, React renders 0 before the list. Use explicit checks:

{items.length > 0 && items.map(item => <div>{item}</div>)}
Enter fullscreen mode Exit fullscreen mode

7. JSX Is Not HTML ๐Ÿ–‹๏ธ

JSX looks like HTML but isnโ€™t! For example, the class attribute is className, and self-closing tags must end with a /.

<div className="my-class" />;
Enter fullscreen mode Exit fullscreen mode

8. Infinite Loops With useEffect ๐Ÿ”„

Forgetting to add dependencies in useEffect can create infinite loops.

useEffect(() => {
    fetchData();
}, [data]); // Missing `data` can cause repeated calls
Enter fullscreen mode Exit fullscreen mode

Solution: Use the dependency array carefully or useRef for stable references.

9. Fragments Donโ€™t Accept Keys By Default ๐Ÿ”‘

When using React.Fragment to wrap multiple elements, you might need to add a key, especially in lists.

<>
    <div key="1">Item 1</div>
    <div key="2">Item 2</div>
</>
Enter fullscreen mode Exit fullscreen mode

Solution: Use instead if required.

10. Updating State Doesnโ€™t Merge Objects โœ‚๏ธ

Unlike this.setState in class components, useState doesnโ€™t merge object state automatically.

const [state, setState] = useState({ name: 'React', version: 18 });

setState({ version: 19 }); 
// Name is lost because the state isnโ€™t merged!
Enter fullscreen mode Exit fullscreen mode

Solution: Spread the previous state:

setState(prevState => ({ ...prevState, version: 19 }));
Enter fullscreen mode Exit fullscreen mode

Conclusion: React Is Full of Surprises! ๐ŸŽ‰
Understanding these quirks will make you a better React developer. What are some quirks youโ€™ve encountered? Drop your answers in the comments below! Letโ€™s discuss! ๐Ÿ˜Ž

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series ๐Ÿ“บ

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series ๐Ÿ‘€

Watch the Youtube series

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay