@ -1728,6 +1690,22 @@ html, body { min-height: 300px; }
}
```
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```
</Sandpack>
However, you didn't *have to* do that. As with regular functions, ultimately you decide where to draw the boundaries between different parts of your code. For example, you could also take a very different approach. Instead of keeping the logic in the Effect, you could move most of the imperative logic inside a JavaScript [class:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
@ -2202,6 +2180,22 @@ It looks like your `useInterval` Hook accepts an event listener as an argument.
<Sandpack>
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```
```js
import { useCounter } from './useCounter.js';
import { useInterval } from './useInterval.js';
@ -2233,7 +2227,7 @@ export function useCounter(delay) {
```js useInterval.js
import { useEffect } from 'react';
import { useEvent } from './useEvent.js';
import { experimental_useEvent as useEvent } from 'react';
export function useInterval(onTick, delay) {
useEffect(() => {
@ -2245,25 +2239,6 @@ export function useInterval(onTick, delay) {
}
```
```js useEvent.js
import { useRef, useInsertionEffect, useCallback } from 'react';
// The useEvent API has not yet been added to React,
// so this is a temporary shim to make this sandbox work.
// You're not expected to write code like this yourself.
export function useEvent(fn) {
const ref = useRef(null);
useInsertionEffect(() => {
ref.current = fn;
}, [fn]);
return useCallback((...args) => {
const f = ref.current;
return f(...args);
}, []);
}
```
</Sandpack>
<Solution>
@ -2276,6 +2251,23 @@ With this change, both intervals work as expected and don't interfere with each
<Sandpack>
```json package.json hidden
{
"dependencies": {
"react": "experimental",
"react-dom": "experimental",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```
```js
import { useCounter } from './useCounter.js';
import { useInterval } from './useInterval.js';
@ -2307,7 +2299,7 @@ export function useCounter(delay) {
```js useInterval.js active
import { useEffect } from 'react';
import { useEvent } from './useEvent.js';
import { experimental_useEvent as useEvent } from 'react';
export function useInterval(callback, delay) {
const onTick = useEvent(callback);
@ -2318,25 +2310,6 @@ export function useInterval(callback, delay) {
}
```
```js useEvent.js
import { useRef, useInsertionEffect, useCallback } from 'react';
// The useEvent API has not yet been added to React,
// so this is a temporary shim to make this sandbox work.
// You're not expected to write code like this yourself.