Undefined
Undefined

Reputation: 1021

Variable not defined in React typescript

I am making a simple React application in which there is a app.tsx file with the code as follows,

export default function App() {
  const initializeData = () => {
    const dataScript = document.createElement("script");
    dataScript.type = "text/javascript";
    dataScript.textContent = `
    let data = { 'name': "" };`;
    document.head.appendChild(dataScript);
  };

  React.useEffect(() => {
    initializeData();
  }, []);

  return (
    <div className="App">
      {console.log(data)}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

-> Where initializeData method will intialize a global data and that will be available for all other pages (considering all components will be called from here in app.tsx ).

-> Calling the method from useEffect lifecycle hook like,

  React.useEffect(() => {
    initializeData();
  }, []);

-> Trying to console.log the data in template like,

 return (
    <div className="App">
      {console.log(data)}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );

Error:

This line {console.log(data)} throws the error as data is not defined

Requirement:

Need to make a variable declaration in global level so those variables would be available for all files.

Keeping this in mind only I have tried assigning it in head tag inside script tag but this shows error in typescript.

Edit stupefied-newton-ixwut

Please help me on how to assign a global variable and access it inside any files..

Upvotes: 1

Views: 2413

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074028

Your useEffect callback doesn't run until after your attempt to use the data variable in the JSX you're returning. From the useEffect documentation:

The function passed to useEffect will run after the render is committed to the screen.

The order in which things happen when your App function is first called is:

  1. The initializeData function is created.
  2. Your useEffect callback function is created.
  3. useEffect is called with that callback and an empty array.
  4. Your JSX is evaluated, including the console.log(data) call — causing the error.

If it weren't for the error, things would continue like this:

  1. The React element (and its children) you return would be put in the DOM by React.
  2. Then React would call your useEffect callback, which would create the script element creating the global variable.

You could use typeof data === "undefined" to know that it's the first render and data may not exist yet, but you'll also need to do something else to make your component function get called again (e.g., have a state variable you update in your useEffect callback). But creating a global variable when a component mounts is, to put it mildly, not best practice and I strongly recommend you look to solve your underlying requirement in a different way.

Upvotes: 1

Related Questions