My thought:
I know that in React I can get it work by using class component and document.getElementById() and all those, however I am just wondering why it is not working here.
Why the same code works in normal html but not in React? Is it something to do with the sequence of how the codes are being executed? Or what else?
I’m not sure that the original vanilla js way is a good pattern. I think it’s typically a better idea to have a reference to the dom Audio Object HTML DOM Audio play() Method).
In React, using the Document object is an anti-pattern as you should avoid manipulating the dom directly. Check out the useRef hook for that!
“Q” in “Q.play()” isn’t something that the browser would know what it is either. And it shouldnt have the () because that means “execute” and you want it to be able to be executed. Maybe you meant onClick="play" and that function was defined somewhere?
Or maybe onClick="()=>{document.getElementById("Q").play()}" but idk whether this would work (and yet isn’t a good idea).
I get your point that there should not be the () here, but weirdly this code works like this, that it just calls the play method of the audio with the id Q, not another play method I defined somewhere else.
Yeah, and this code using document.getElementById works in React. Thanks. But I’m still not get why the same code works in normal html does not work in React.
The second one isn’t HTML, it’s JavaScript (JSX is something that’s translated to JS, it’s just dressed up to look like HTML to make it clear what the intention is), and there is no variable called Q. So when it’s rendered as HTML, there’s an event listener added that tries to run undefined.play()
As stated, you need a ref to do what you’re trying to do, which allows you to bypass how React normally works and will give you access to the actual DOM that eventually gets rendered.
The first one works because what browsers do with id attributes in actual HTML is set them as global JS variables (hence why ids in HTML have to be unique – if you had two called Q on a page, the second one would overwrite the first one). So there is an audio DOM element assigned to the variable Q, and audio objects have the method play. (Edit: relying on this behaviour is not a good idea, I can’t remember the caveats off the top of my head, but it definitely doesn’t work in some situations)
Yeah, so JS was originally just a very very lightweight way to add a sprinkling of interactivity to HTML when it couldn’t be done any other way. So there are quite a few things which were designed to make it convenient in that context. It not as if you’d try to use JS to build entire apps or anything ! Once JS started being used for much more complex things…turns out a lot of the “convenient” things ended up being weird annoyances, but anyway:
Neat explanation. I didn’t know that is why you can just call the ids like that in the console. I thought it was a feature of the dev tool.
But it is not the other way around, variables that you define in the “upper level” of the JS script won’t overwrite those globals, I think?
So we only “selectById” to be nice to other devs correct? Cause we could just use those variables? (sorry for the many Qs, I will just test some by myself.)