kyun
kyun

Reputation: 10264

re-rendering a component every milliseconds

I made a Countdown component.

It works well as Normal Countdown but I wanna see it works with milliseconds.

But I have no idea how it re-render every millisecond and display milliseconds.

this code is what I made and it re-render every second.

edited

I am considering re-rendering every 100ms or 10ms. and I want to display this.

furthermore, I want to know If it re-rendered every 100ms, whether it is okay or not

const {useState, useEffect} = React;
function Countdown(props){
  const [timer, setTimer] = useState(0);
  const {d,h,m,s} = secToDay(timer);
  useEffect(()=>{ 
    setTimer(props.value) 
  },[]);
  useInterval(()=>{
    setTimer(timer - 1);
    if( (timer-1) === 0){
      // Timeover
    }
  }, timer > 0 ? 1000 : null);
  return (
    <div>
      <span>{d}</span>:
      <span>{h}</span>:
      <span>{m}</span>:
      <span>{s}</span>
    </div>
  )
}

const App = () => (<Countdown value={300} />);
ReactDOM.render(<App />, document.getElementById('root'));


function secToDay(seconds:number){
  let d = (~~(seconds/(3600*24))).toString().padStart(2,'0');
  let h = (~~(seconds % (3600*24) /3600)).toString().padStart(2,'0');
  let m = (~~((seconds % (3600*24) % 3600) / 60)).toString().padStart(2,'0');
  let s = (~~(seconds % 60)).toString().padStart(2,'0');
  return {d,h,m,s};
}
function useInterval(callback: any, delay: any) {
  const savedCallback: any = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  });

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

Upvotes: 0

Views: 1464

Answers (1)

Tony Nguyen
Tony Nguyen

Reputation: 3488

Add ms by s*1000 in secToDay function and change delay to 1 instead of 1000. Run the snippet to see the result.

const {useState, useEffect} = React;
function Countdown(props){
  const [timer, setTimer] = useState(0);
  // add ms
  const {d,h,m,s, ms} = secToDay(timer);
  useEffect(()=>{ 
    setTimer(props.value) 
  },[]);
  useInterval(()=>{
    setTimer(timer - 1);
    if( (timer-1) === 0){
      // Timeover
    }
  }, timer > 0 ? 1 : null); // set delay 1
  return (
    <div>
      <span>{d}</span>:
      <span>{h}</span>:
      <span>{m}</span>:
      <span>{s}</span>:
      <span>{ms}</span>
    </div>
  )
}

const App = () => (<Countdown value={300} />);
ReactDOM.render(<App />, document.getElementById('root'));


function secToDay(seconds:number){
  let d = (~~(seconds/(3600*24))).toString().padStart(2,'0');
  let h = (~~(seconds % (3600*24) /3600)).toString().padStart(2,'0');
  let m = (~~((seconds % (3600*24) % 3600) / 60)).toString().padStart(2,'0');
  let s = (~~(seconds % 60)).toString().padStart(2,'0');
 // add ms
  let ms = s*1000
  return {d,h,m,s,ms};
}
function useInterval(callback: any, delay: any) {
  const savedCallback: any = React.useRef();

  React.useEffect(() => {
    savedCallback.current = callback;
  });

  React.useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

Upvotes: 1

Related Questions