Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to get all classes using document.querySelectorAll in reactjs and manipulate it?

I wanted to allow users to change the theme of the application by picking which theme they want the body’s background color changes and all button colors. But the problem is that whenever I use document.querySelectorAll(‘.btn-theme-1’).style.backgroundColor it tells me that it cannot read those properties.

I know of useRef() but in my case I am trying to select all buttons throughout the entire application. Not just one element in the current component. So I would like to know if there is a way to fix what I am attempting or if I am doing this the wrong way.

Here is the code for what I tried. This is my pick theme component:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import ColorThemes from '../data/ColorThemes';
import { useEffect } from 'react';

const PickTheme = () => {
    const changeTheme = (c) => {
        document.body.style.background = c.default || c.bgColor;
        document.body.style.color = c.bodyColor;
        document.querySelector('.bi-quote').style.color = c.buttonBg;
        document.querySelectorAll('.text-color').forEach(el => el.style.color = c.fontColor)
        document.querySelectorAll('.btn-theme-1').forEach(el => {
            el.style.color = c.buttonColor;
            el.style.backgroundColor = c.buttonBg;
        });
    };

    useEffect(() => {

    },[changeTheme]);

    return(
        ColorThemes.background.map(c => {
            if(c.bgColor) {
                return(
                    <button type="button" key={c.bgColor} className="btn btn-light me-2 p-3 rounded-5" onClick={() => changeTheme(c)} style={{backgroundColor: c.bgColor}}></button>
                );
            } else {
                return(
                    <><br/><button type="button" key={c.default} className="btn btn-light me-2 mt-2 rounded-5" onClick={() => changeTheme(c)}>Default</button></>
                );
            }
        })
    );
};

export default PickTheme;

It successfully changes the bodys color and background color but not the other classes. I tried with and without useEffect and still receive the same issue.

If I comment out everything except the last selector, the buttons then change colors. So maybe it is conflicting or cannot change everything at once, for example:


    const changeTheme = (c) => {
        // document.body.style.background = c.default || c.bgColor;
        // document.body.style.color = c.bodyColor;
        // document.querySelector('.bi-quote').style.color = c.buttonBg;
        // document.querySelectorAll('.text-color').forEach(el => el.style.color = c.fontColor)
        document.querySelectorAll('.btn-theme-1').forEach(el => {
            el.style.color = c.buttonColor;
            el.style.backgroundColor = c.buttonBg;
        });
    };

This changes the buttons background and color after commenting out the other parts.

>Solution :

I know of useRef() but in my case I am trying to select all buttons throughout the entire application. Not just one element in the current component.

Using .querySelector or any other selector will select only those elements that are currently rendered, actually. So if you e.g. toggle the state and component re-renders with different elements, they will not be affected with your change, which will result in partially toggled theme for different elements.

You should either set a context, wrapping whole App or set a redux variable holding info which theme is currently selected. Then, you will be able to manipulate styles using e.g. theme in styled components: https://styled-components.com/docs/advanced#theming or just toggling classNames with css modules, basing on that variable.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading