Can you talk a little about the pain points you encountered, which this presumably solves?
Sure! There are several, but let's take a trivial one - setTimeout. This is an example of something that is inherently imperative, and therefore requires some awkward logic to get it working correctly in React. Here's an article explaining how to do it: https://codedamn.com/news/reactjs/how-to-use-settimeout-in-r... In contrast, here's how you would do it in matry: let someValue = 0; setTimeout(() => { someValue++; s…
> There's no special concept to understand
By not understanding that you need to cleanup timers when your view unmounts, you've introduced a subtle bug that your coworker will discover in 6 months when users report that the counter sometimes increases twice as fast.
I've worked on Angular-like apps before, and storing and cleaning up timers was always a pain point:
private timer
private someValue = 0
onMount() {
timer = setTimeout(() => {
someValue++;
setContent(value is {someValue})
}, 1000)
}
onUnmount() {
clearTimeout(timer)
}
React on the other hand, clearly defines the concept of an effect as something that is initiated after the component renders and then cleaned up. You also keep the setup and cleanup close together, so you don't need to manually store the timer handle. const [someValue, setSomeValue] = useState(0)
useEffect(() => {
const timeout = setTimeout(() => {
setSomeValue(v => v + 1)
}, 1000)
return () => clearTimeout(timeout)
}, [])
return value is {someValue}
People often criticise useEffect for being hard to grasp, but it is the perfect essence of how to manage, well... effects in a component-based system.That's why Vue and Svelte have the same thing: https://vuejs.org/guide/essentials/watchers.html https://svelte.dev/blog/runes