Any idea why dangerouslySetInnerHTML doesn't seem to be working?

I am trying to use dangerouslySetInnerHTML, but it never shows up on the screen. I did many console.log()'s to check if anything is undefined, but everything seems to exist. This is the 3 Position React Toggle Switch With Forward, Reverse, And An Unlocked Track 2. This is the React component version of the 3 Position Toggle Switch With Forward, Reverse, And An Unlocked Track vanilla JavaScript version. That version let’s you know which option is selected and I used innerHTML for that one. The dangerouslySetInnerHTML is on line 223. The console.log()'s for testing purposes are on lines 178 to 185. The displaySelectedOption() function that is supposed to supply the value for the dangerouslySetInnerHTML is on lines 151 to 159. I also tried placing a displaySelectedOption() function inside the render() method, but it seems to have scope issues, so I had to comment it out and it is located on lines 170 to 176. What do you think might be the issue? Thanks for any help and have a nice day!

Edit: Link to React component changed to final version.

It doesn’t work because you’re supposed to provide it with a value. displaySelectedOption doesn’t return a value since it’s calling setTimeout.

What you’re supposed to do in React is to set props and state variables and then use those in render() to display things appropriately. You don’t access the HTML elements and store the reference in the state, that’s a hack and completely against React’s philosophy, you would be better off writing vanilla javascript. You define your state, e.g. you could have this.switchPosition which would have three possible values depending on the state (e.g. 0, 1, 2 or ‘left’, ‘middle’, ‘right’ or whatever), set it to its starting position in the constructor, and change its value in the click handler (or if you want something closer to your current implementation you could have this.radioButtonsArray[] but the values wouldn’t come from the html, it would be the starting values that you give your program). You don’t touch the HTML elements, you just add checked={selected} in each <input> where selected is true/false, which you deduce from the state.

1 Like

Thanks a lot for your reply!

I ended up scrapping the React component and doing an entirely new one following your suggestions. This one uses about half the React and JavaScript code and about half the CSS. The new React component is the 3 Position React Toggle Switch With Forward, Reverse, And An Unlocked Track 7. I also decided not to use dangerouslySetInnerHTML because the React folks seem to highly discourage it. I used it in the Markdown Previewer project and was hoping to get more experience in using it for the Drum Machine project.

Let me know what you think. Is this one more in line with the principles of React than the previous one? The previous one was the 3 Position React Toggle Switch With Forward, Reverse, And An Unlocked Track 2. Thanks again for your help.

Btw, it ended up being much easier for me to write this from scratch than it was to fork the original HTML and CSS project, add JavaScript, and then turn all that into a React component.

Edit: Links to React components changed to final version.

Hi, I looked at your latest version. Yes, it’s much more in line with the React principles.

I notice you’re still using document.getElementById, which is dangerous in React. You could set the colour in render but for the animation it might not work so well. So the best option here is to use a ref:

A few more points:

  • Be careful when using ids in components, because each HTML id is supposed to be unique in the document. What if you wanted to build a page with two toggle switch components? In cases like this it’s often better to use a class than an id.

  • This is a minor point but selectedOption and slidingButtonPosition seem to be expressing the same thing in different ways. I’m pretty sure you could use only one of them.

  • For an additional challenge, you could try to make it work with the keyboard.

1 Like

Thanks again!

This is the 3 Way React Switch Forward Reversed Locked Track. I shortened the name a little because it was difficult to tell which version was which in the CodePen dashboard.

I changed some things:

  • Removed all of the document.getElementById()'s.

  • Implemented 4 ref’s.

  • Removed the slidingButtonPosition state property.

  • Added keyboard support with the left and right arrow keys moving the sliding button in those directions using the newly added keyboardPress() method.

  • Added the componentDidMount() lifecyle method to focus on the application when it loads.

  • Added a tabIndex to the outermost div to be able to focus on it.

  • Added the onKeyDown event handler to the outermost div to detect keyboard presses.

I left the id’s in place and only used them for the CSS. Is this acceptable, or are classes always preferred?

Thanks again.

Btw, I am surprised I didn’t need the setTimeout() method at all. Although I didn’t use that method in the Random Quote Generator (RQG) project or the Markdown Previewer (MP) project, I have used it extensively on the Drum Machine (DM) project. The RQG was pretty simple and I didn’t really add any features so everything was synchronized and worked fine. In the MP, I added a few features and when things weren’t synchronized, I would just add another conditional statement and things would work, but the code became very bloated.

In the DM, I found out about setTimeout() and used it extensively. This fixed many issues for me. I guess I just used React the wrong way, so I had many synchronization issues.

Is using setTimeout() extensively a sign that you may be doing something wrong with React?

1 Like

Nice job!

Regarding id vs class, I think the consensus is that, for styling, class is better. When you write style as class, if later down the line you need another element with the same style, it’s easier to change than if it was implemented as an id. It just makes your life easier, that’s why it’s best practice. But id works too, so it’s up to you.

There are still situations where you must use id: using getElementById (which you wouldn’t normally use in React code but you can use it for testing), the fragment part of a url, labels… But it doesn’t prevent you from using a class for styling.

Regarding setTimeout, I’m not sure. If you’re using setTimeout to get around how React works, I guess it’s a code smell, but if you use it to do something truly asynchronous in nature, like say a countdown, then it makes perfect sense. You’d use the setTimeout to change the state and let React handle the render in its own time.

1 Like

Thank you so much for all of your help! My understanding of React has improved tremendously!

I will implement this switch in the Drum Machine project and will refactor the whole project to use React properly. Thanks again!

1 Like