---
title: "MotionValue `.on(\"change\")` subscription in a component body (lint/motionvalue-subscribe-in-render)"
description: "lint/motionvalue-subscribe-in-render: Subscribing during render adds a new listener on every render and never unsubscribes, so callbacks multiply and memory…"
canonical: https://void-design.vercel.app/rules/lint/motionvalue-subscribe-in-render
lastModified: 2026-09-16
---

# MotionValue `.on("change")` subscription in a component body

`lint/motionvalue-subscribe-in-render` · severity **error** · category Lint · detected by `void lint` and `void audit`

## Why it matters

Subscribing during render adds a new listener on every render and never unsubscribes, so callbacks multiply and memory grows while the animation runs.

## How to fix it

Use `useMotionValueEvent(value, 'change', cb)`, or subscribe in `useEffect` and return the unsubscribe function.

## Example

```tsx
useMotionValueEvent(scrollY, 'change', (y) => setScrolled(y > 8))
```

## References

- https://motion.dev/docs/react-use-motion-value-event

## More lint rules

`void lint` reports 67 rules in this category. Static source checks with no browser: Tailwind v4 silent failures, Next.js 16 API traps, React render-body bugs, accessibility markup, SEO files and motion hygiene.

- `too-many-font-families` More than 3 font families loaded — [lint/too-many-font-families](https://void-design.vercel.app/rules/lint/too-many-font-families)
- `script-strategy` Third-party script loads too early — [lint/script-strategy](https://void-design.vercel.app/rules/lint/script-strategy)
- `browser-global-in-render` Browser global (`window`, `document`, `navigator`, `localStorage`) at module scope or during render — [lint/browser-global-in-render](https://void-design.vercel.app/rules/lint/browser-global-in-render)
- `timer-in-render` `setTimeout` / `setInterval` called in a component body — [lint/timer-in-render](https://void-design.vercel.app/rules/lint/timer-in-render)
- `webgl-in-map` WebGL canvas rendered inside `.map()` — [lint/webgl-in-map](https://void-design.vercel.app/rules/lint/webgl-in-map)
- `raf-without-cancel` `requestAnimationFrame` loop in an effect without `cancelAnimationFrame` — [lint/raf-without-cancel](https://void-design.vercel.app/rules/lint/raf-without-cancel)
- `listener-without-cleanup` Event listener or interval added in an effect without cleanup — [lint/listener-without-cleanup](https://void-design.vercel.app/rules/lint/listener-without-cleanup)
- `scroll-listener-nonpassive` `wheel` / `touchstart` / `touchmove` listener without `{ passive: true }` — [lint/scroll-listener-nonpassive](https://void-design.vercel.app/rules/lint/scroll-listener-nonpassive)

Detected by `void lint` and `void audit`. Explain it in a terminal: `void rules lint/motionvalue-subscribe-in-render`
