-1

I have been trying to use createElement inside an if statement but it just doesn't work. The headerLink is not recognized outside of the if statement.

Can someone explain what's missing?

What I have tried so far:

  1. Declaring headerLink outside the if statement. This doesn't work

  2. If I move the appendChild and removeChild inside the if statement, it starts to work. But, that would result in duplicate code since I will need to copy the same inside the else statement

    React.useEffect(() => {
        const head = document.head;
        const scriptType = "text/css";
    
    
        if (scriptType === "text/css") {
            const headerLink = document.createElement( "link" );
        } else {
            const headerLink = document.createElement( "script" ); 
        }
    
    
        // this line doesn't work - headerLink is not recognized
        head.appendChild(headerLink);
    
        return () => {  
            // this line doesn't work - again, headerLink is not recognized
            head.removeChild(headerLink);
        };
    }, []);
    
Andy
  • 61,948
  • 13
  • 68
  • 95
Danish Muneer
  • 568
  • 1
  • 9
  • 22
  • const is block scoped. You define it in a block and try to use outside – Wiktor Zychla Mar 04 '22 at 06:18
  • what would be the alternative? I tried `let` and that also didn't work – Danish Muneer Mar 04 '22 at 06:19
  • let us also block scoped. var isn't – Wiktor Zychla Mar 04 '22 at 06:20
  • You need to declare the variable outside of the if/else blocks, otherwise it isn't visible to subsequent statements. Worth brushing up on [MDN how to use const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const). – Serlite Mar 04 '22 at 06:20
  • 1
    I would suggest declaring something like let myElement = "link" and using an if block to change it if necessary, then creating the element – Sandil Ranasinghe Mar 04 '22 at 06:22
  • It's not clear what you're trying to do. You probably shouldn't be using native DOM methods with React in that way. – Andy Mar 04 '22 at 06:23
  • Does this answer your question? [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – Serlite Mar 04 '22 at 06:24

2 Answers2

3

You can move the declaration of the headerLink outside the if clause. But you will have to use let in that case.

let headerLink;

if (scriptType === "text/css") {
    headerLink = document.createElement( "link" );
} else {
    headerLink = document.createElement( "script" ); 
}

Or you can use ternary conditional operator to create element

const headerLink = document.createElement( scriptType === "text/css" ? "link" : "script" );
Aditya
  • 315
  • 1
  • 9
  • Do you think this is a reasonable approach for React? – Andy Mar 04 '22 at 06:27
  • I agree with your comment above that DOM should not be manipulated if using React. But the above question had limited context and it specifically asked about the DOM. – Aditya Mar 04 '22 at 06:32
  • The context it's being used in a `useEffect`. The code doesn't make any sense. `scriptType` will always be `"text/css"`. It answers one question, but doesn't resolve all the other ones. – Andy Mar 04 '22 at 06:37
  • thanks, yes I used let and it worked. Only thing I was missing were the types. Posting that version below – Danish Muneer Mar 04 '22 at 06:38
0

Building upon Aditya's answer and Sandil's comment above, resolved the issue

useEffect(() => {

        const head = document.head;

        let headerScript: HTMLLinkElement | HTMLScriptElement;

 

        if(scriptType === "text/css") {

            headerScript = document.createElement( "link" );

        } else {

            headerScript = document.createElement( "script" );

        }

        head.appendChild(headerScript);

 

        return () => {

            head.removeChild(headerScript);

        };

       

        

    }, []);
Danish Muneer
  • 568
  • 1
  • 9
  • 22