Home > database >  Stopwatch restarts on conditional rendering
Stopwatch restarts on conditional rendering

Time:12-28

I am using the package 'react-timer-hook' to create a stopwatch each time an order is added to an array. The issue was that every stopwatch, throughout all the components would reset to zero, and I could not figure out why. After much experimentation I discovered the issue. The components containing the stopwatch were children of a component which was conditionaly rendered, based on a boolean state.

In this fiddle I demonstrate the issue. If you add a number of orders to the array, each will have an independant stopwatch. However, once you hide the list, then show, all those(conditionally rendered) will be reset.

I am just learning react, but I was under the impression that the key would identify the component as unique, hence preventing the rerender. Am I breaking some cardinal sin without understanding? Is there some way to get around this, possibly by providing a key identifier higher up the component tree? I deeply appreciate any input.

This is a follow up to this quesiton, which I asked a few days ago.

I tried many things, as documented in the previous question.

CodePudding user response:

Basically, the problem is that your component unmounts from the dom when you hide it and is mounted/rendered again when you click on show. So because const { seconds, minutes } = useStopwatch({ autoStart: true }); this hook is inside Stopwatch component it is called for all the items in the array and time starts again from 0 for all the array. To overcome this problem of resetting you should hide the display by css instead of conditional rendering.

here is an approach you can follow, comment the conditional rendering and add conditional style

       {/* {isShow && ( */} 
    <div style={{ display: !isShow && "none" }}>
      <button onClick={() => handleClick()}>hide</button>
      <button onClick={() => handleAddStopwatch()}>add</button>
      <div>Conditional render</div>
      {orderArray &&
        orderArray.map((order) => {
          return (
            <div key={order.id}>
              <div>
                ID :{order.id}--
                <Stopwatch />
              </div>
            </div>
          );
        })}
    </div>
    {/* )} */}
  • Related