I’m working on the Drum Machine project in React, but I’ve having problems passing the value from an object to the triggerSound function.
-I’ve created a const object allKeys right after the render(). In it the keys are src (a url) and desc (description).
-The buttons are declared inside the return statement, and they are accessing the allKeys.src correctly:
ie: src={allKeys.Q.src}
-The triggerSound function is able to read the src and play the correct audio:
document.getElementById(e.target.id).firstElementChild.src
But since the button doesn’t have the allKeys.desc, it can’t access those values with a document.getElementById. The object is a constant, so shouldn’t it be accessible within the function?
Can you post code that includes what you talk about? There isn’t an object that matches your description in that code.
There are a few things that aren’t correct though here, I’m not sure you’re quite getting how React works.
- You don’t need
getElementById
and you can’t use it the way you’re trying to do, you don’t need that with React. There is absolutely zero need to render to the DOM, read values from the DOM, then send those value back into React — you already have the values, you’ve just added an extra massive layer of complexity for no reason.
- You should never set the state directly, this is why React provides the
setState
method.
I’m fairly new at React and it’s a little bit confusing. I’ve gone through all the lessons but I can’t quite put everything together yet.
A: This is the const allKeys I was talking about:
render() {
const allKeys = {
Q: {src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3", desc: "First!"},
W: {src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3", desc: "Second!"},
E: {src: "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3", desc: "Third!"},
etc...
1: Okay, React shouldn’t use getElementById. So this part is wrong:
var currClip = document.getElementById(e.target.id).firstElementChild.src;
Should I do something like this instead?
var currClip = e.target.id.firstElementChild.src
(I can get the ID this way, but I can’t get the firstElementChild or the audio element. The audio has the src which is being pulled from the allKeys.)
2: Right, any states should be changed within the setState {}. So I should create a this.state.currClip instead of using var currClip.
Are you currently working on click to play or press to play?
I’m currently working on click to play.
-Click to play works, but it’s using the document.getElementById (which is wrong).
-Press to play doesn’t work.
-Show description of sound doesn’t work.
Using the document.getElementById is fine.
What does your onClick function look like?
edit: nvm looking at ur codepen
-
You made it so that it is hard to access the object that you created.
You can create a global object, by creating the object outside of your class.
You have it inside of your render() { const object = {…}}, making it hard for you to access the object.
-
If you wanted your keypress to work, you’d have to have the right value of the keycode in your object.
const allKeys = {
Q: {src: “https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3”, desc: “First!”, keyCode: 113}
};
http://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html
this is the list of codes that you’d have to apply. Use the lower case ones even if its uppercase.
Bigger problem could be accessing that keycode in your object with the function you created. Try creating a global object and accessing it from there.
I should have been a bit clearer maybe - obviously it works, it’s just that, if this is what you’re doing, then there’s no point in using React. It’s not making anything easier, it’s just adding a heavy framework for zero benefit: you’re not really using React here, given the way you’ve set this up. It would be much simpler to drop React, with the side effect that it should make your original problem much easier to fix.
For example, you don’t store state in an object in your render function, or generally even in a global variable [unless there are some specific rules regarding it (redux does this for example)]. You already have state on the component (and you can also pass props to the component). You can load things in callbacks on the component - for example, audio files you may well be using. If you are just keeping a list of stuff in global objects and using DOM methods, don’t use React, there’s no real point
@ymoon715:
1: So instead of placing the object right after the render(), it should be somewhere else like at the very top of the script? Or is this bad-form for React?
2: Oh, I should store the keyCode for each button in the object too! That’s much simpler than what I was planning to do (a switch statement that checks which keyCode was pressed).
@DanCouper:
I would like to use React for this project, to understand it better. I’m just not understanding the fundamentals right now.
React uses states. Should I be storing the entire object in state instead of making it a Global object? That seems like overkill… Or what if state stores the current button being clicked/keyed?
Its not bad practice to do so, because eventually when you are using a code editor instead of code pen, people make separate files for some objects and strings, import them into components for them to use. In codepen, you would simply make the object separately. Very top would work. Its not considered bad practice. In fact its considered good practice. My homie from Amazon told me to get used to it
It really is situational. Sometimes you can use it inside render, but in this case because it will make it a lot easier to access the object where you are creating the play and press handlers.
Yes @DanCouper is right when he says doing it the way you did using getElementById is not the “React” way, and that it might be just easier not using React at all. But you can keep doing what you are doing, try to make it work with how you are doing it. build more projects, and once you learn more and improve, come back to this project and you will see what he meant.
I used a lot of getElementBy… Or query selectors earlier on but now i rarely use them as I got much better