Skip to content

Commit 4917bdb

Browse files
committed
ad first cursor rule
1 parent 6288ec8 commit 4917bdb

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

.cursor/rules/avoid-use-effect.mdc

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
description:
3+
globs: *.tsx,*.jsx
4+
alwaysApply: false
5+
---
6+
### Avoid useEffect
7+
8+
[You Might Not Need `useEffect`](https://react.dev/learn/you-might-not-need-an-effect)
9+
10+
Instead of using `useEffect`, use ref callbacks, event handlers with
11+
`flushSync`, css, `useSyncExternalStore`, etc.
12+
13+
```tsx
14+
// This example was ripped from the docs:
15+
// ✅ Good
16+
function ProductPage({ product, addToCart }) {
17+
function buyProduct() {
18+
addToCart(product)
19+
showNotification(`Added ${product.name} to the shopping cart!`)
20+
}
21+
22+
function handleBuyClick() {
23+
buyProduct()
24+
}
25+
26+
function handleCheckoutClick() {
27+
buyProduct()
28+
navigateTo('/checkout')
29+
}
30+
// ...
31+
}
32+
33+
useEffect(() => {
34+
setCount(count + 1)
35+
}, [count])
36+
37+
// ❌ Avoid
38+
function ProductPage({ product, addToCart }) {
39+
useEffect(() => {
40+
if (product.isInCart) {
41+
showNotification(`Added ${product.name} to the shopping cart!`)
42+
}
43+
}, [product])
44+
45+
function handleBuyClick() {
46+
addToCart(product)
47+
}
48+
49+
function handleCheckoutClick() {
50+
addToCart(product)
51+
navigateTo('/checkout')
52+
}
53+
// ...
54+
}
55+
```
56+
57+
There are a lot more examples in the docs. `useEffect` is not banned or
58+
anything. There are just better ways to handle most cases.
59+
60+
Here's an example of a situation where `useEffect` is appropriate:
61+
62+
```tsx
63+
// ✅ Good
64+
useEffect(() => {
65+
const controller = new AbortController()
66+
67+
window.addEventListener(
68+
'keydown',
69+
(event: KeyboardEvent) => {
70+
if (event.key !== 'Escape') return
71+
72+
// do something based on escape key being pressed
73+
},
74+
{ signal: controller.signal },
75+
)
76+
77+
return () => {
78+
controller.abort()
79+
}
80+
}, [])
81+
```

0 commit comments

Comments
 (0)