Carlos Jaime C. De Leon
Carlos Jaime C. De Leon

Reputation: 2906

react-helmet changing css in the head tag during runtime has lag (no css for 1 sec before it shows updated css)

This is a simplified React component that uses helmet to update the link css on runtime:

function App() {
  const [brand, setBrand] = useState('nike')
  return (
    <div className="App">
      <Helmet>
        <link rel="stylesheet" href={getBrandStyle(brand)} />
      </Helmet> 
      <div>other contents here</div>
      <!-- omitted the button components that change the brand state by calling setBrand -->
    </div>
  );
}

I have recently just used react-helmet as a declarative way to change the head tag's child and with the code I wrote above, when switching the css there is momentary lag when the page has no css stylings and then 1 second later the updated css shows up.

Even during the initial load of the page, if I use queryParameters (code above doesn't show the query parameter approach) such as

https://localhost:3000?brandQueryParam=nike

there is 1 second wherein there is no css styling before the brand css shows up.

Can you please let me know what I am missing and how to resolve this?

Upvotes: 0

Views: 2083

Answers (1)

Carlos Jaime C. De Leon
Carlos Jaime C. De Leon

Reputation: 2906

This is the solution that I came up with, not sure if setTimeout is the best solution so if anyone else knows a better way, please share it.

const brands = {
  nike: 'nike2022',
  adidas: 'adidas2017',
  fila: 'fila2020'
};

function App() {
  const [brand, setBrand] = useState('nike')
  const [isLoading, setIsLoading] = useState(false)
  const changeBrandStyleOnClick = (brand) => {
    setBrand(brand)
    setIsLoading(true)
  }

  return (
    <div className="App">
      <Helmet>
        <link rel="stylesheet" 
              onChangeClientState={(newState, addedTags, removedTags) => setTimeout(() => setIsLoading(false), 1500)}
              href={getBrandStyle(brand)} />
      </Helmet> 
      {isLoading && (
        <Overlay>
          <Spinner/>
        </Overlay>
      )}

      {!isLoading && (
        <>
          {Object.keys(brands).filter(b => b !== brand).map(b =>
            (<Button onClick={() => changeBrandStyleOnClick (b)} value={b}>
            <Logo
              alt="default alt name"
              appearance="default"
              name={b}
              size="small"/>
            </Button>))
          }
          <div>other contents here</div>
        </>
      )}
    </div>
  );
}

Upvotes: 0

Related Questions