Home > Blockchain >  useEffect is called before the custom font is loaded
useEffect is called before the custom font is loaded

Time:05-17

In my app I am using a custom font

@font-face {
  font-family: "Koulen";
  src: url("./assets/fonts/Koulen-Regular.ttf") format("truetype");
}

body {
  font-family: "Koulen";
}

Unfortunately this causes problems because the useEffect is called before the custom font is loaded. This causes issues in layout calculations.

import React, { useEffect, useRef } from 'react';
import './App.css';

function App() {
  const rectangleRef = useRef(null);

  useEffect(() => {
    console.log("USE EFFECT WIDTH", rectangleRef.current!.clientWidth);
  }, []);

  const calculateWidth = () => {
    console.log("ON CLICK WIDTH", rectangleRef.current!.clientWidth);
  };

  return (
    <div className="App">
      <header className="App-header">
        <p ref={rectangleRef} className="rectangle">
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <button onClick={calculateWidth}>Calculate width</button>
      </header>
    </div>
  );
}

After I run the app and click the "Calculate width" button, I get:

enter image description here

As you can the useEffect ran the layout calculations before my custom font is loaded. How can I fix this?

CodePudding user response:

You can try using documents.fonts.ready -

useEffect(() => {
    document.fonts.ready.then(function () {
      // Any operation that needs to be done only after all the fonts
      // have finished loading can go here.
    });
  }, []);

CodePudding user response:

import React, { useEffect, useRef } from "react";
import "./App.css";

export default function App() {
  const rectangleRef = useRef(null);

  useEffect(() => {
    if (
      rectangleRef.current &&
      window
        .getComputedStyle(rectangleRef.current, null)
        .getPropertyValue("font-family") === "Koulen"
    ) {
      console.log("With USE EFFECT WIDTH", rectangleRef.current.clientWidth);
    } else {
      console.log("Without USE EFFECT WIDTH", rectangleRef.current.clientWidth);
    }
  }, [rectangleRef]);

  const calculateWidth = () => {
    console.log("ON CLICK WIDTH", rectangleRef.current.clientWidth);
  };

  return (
    <div className="App">
      <header className="App-header">
        <p ref={rectangleRef} className="rectangle">
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <button onClick={calculateWidth}>Calculate width</button>
      </header>
    </div>
  );
}

Check the sandbox

  • Related