skip to Main Content

There is a delay state variable controlled by a slider, but its value is not used.
Pass the delay value to your custom useCounter Hook, and change the useCounter Hook to use the passed delay instead of hardcoding 1000 ms.
Here is the code:

//App.js
import { useState } from 'react';
import { useCounter } from './useCounter.js';
export default function Counter() {
  const [delay, setDelay] = useState(1000);
  const count = useCounter();
  return (
    <>
      <label>
        Tick duration: {delay} ms
        <br />
        <input
          type="range"
          value={delay}
          min="10"
          max="2000"
          onChange={e => setDelay(Number(e.target.value))}
        />
      </label>
      <hr />
      <h1>Ticks: {count}</h1>
    </>
  );
}
//useCounter.js
import { useState, useEffect } from 'react';
export function useCounter(delay) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1);
    }, delay);
    return () => clearInterval(id);
  }, [delay]);
  return count;
}

I’ve been trying to make the useCounter hook respect the delay set by the user in the Counter component, but it doesn’t work.

2

Answers


  1. I think you forgot to give the useCounter function its variable.

    Try passing the delay variable to your useCounter function like so:

    useCounter(delay)

    Login or Signup to reply.
  2. You could move the delay into the custom hook, and then return it, count, and the setters.

    const { useState, useEffect, Fragment } = React;
    
    function useCounter() {
    
      const [delay, setDelay] = useState(1000);
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const id = setInterval(() => {
          setCount(c => c + 1);
        }, delay);
        return () => clearInterval(id);
      }, [delay]);
    
      return {count, delay, setCount, setDelay};
    }
    
    function Example() {
    
      const {count, delay, setCount, setDelay} = useCounter();
    
      return (
        <Fragment>
          <label>
            Tick duration: {delay} ms
            <br />
            <input
              type="range"
              value={delay}
              min="10"
              max="2000"
              onChange={e => setDelay(Number(e.target.value))}
            />
          </label>
          <hr />
          <h1>Ticks: {count}</h1>
        </Fragment>
      );
    }
    
    const node = document.getElementById('root');
    const root = ReactDOM.createRoot(node);
    root.render(<Example />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search