I am trying to create a dark mode of my app for which I have created a state on which I am trying to change background color which is working but when I tried to change background color of my textarea tag I used ternary operator because I want to use different color over there, at that time its not working.
this is my main app which I am using as parent component, from here I am trying to convert my app into dark mode, and here it’s code
import './App.css';
import Navbar from './Components/Navbar';
import TextForm from './Components/TextForm';
import React, {useState} from 'react'
function App() {
const [mode,setMode] = useState('light')
const toggleMode = ()=>{
if(mode === "light"){
setMode("dark");
document.body.style.backgroundColor="black";
}
else{
setMode("light");
document.body.style.backgroundColor="white";
}
}
return(
<>
<Navbar title="demo web" mode={mode} toggledark={toggleMode}/>
<div className="container my-5">
<TextForm heading="Enter text to analyze below"/>
</div>
</>
)
}
export default App;
and here is the code of my nabber on which I have that toggle button on which I have to click to switch on dark mode
export default function Navbar(props) {
return (
<>
<div>
<nav className={`navbar navbar-expand-lg bg-body-tertiary bg-${props.mode}`} data-bs-theme={props.mode}>
<div className="container-fluid">
<a className="navbar-brand" href="/#">{props.title.toUpperCase()}</a>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item">
<a className="nav-link active" aria-current="page" href="/#">Home</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/#">About us</a>
</li>
</ul>
</div>
<div className={`form-check form-switch text-${props.mode==="dark"?"light":"dark"}`}>
<input className="form-check-input" onClick={props.toggledark} type="checkbox" role="switch" id="flexSwitchCheckDefault"/>
<label className="form-check-label" htmlFor="flexSwitchCheckDefault">Enable Darkmode</label>
</div>
</div>
</nav>
</div>
</>
)
}
and here is my component code on which I have textarea tag and I want to change it’s background color but its not working
import React, {useState} from 'react'
export default function TextForm(props) {
const [text,textarea] = useState("")
const handleOnChange = (event)=>{
textarea(event.target.value)
}
const upperCaseClick = ()=>{
let newtext = text.toUpperCase()
textarea(newtext)
}
const lowerCaseClick = ()=>{
let newtext = text.toLowerCase()
textarea(newtext)
}
return (
<>
<h1>{props.heading.toUpperCase()}</h1>
<textarea className="form-control" id="exampleFormControlTextarea1" style={{backgroundColor: props.mode==="dark"?"black":"grey"}} onChange={handleOnChange} value={text} placeholder="enter your text" rows="11"></textarea>
<div className='my-3'>
<button className="btn btn-outline-danger" onClick={upperCaseClick}>Convert to Upeercase</button>
<button className="btn btn-outline-success mx-5" onClick={lowerCaseClick}>Convert to Lowercase</button>
</div>
<div className="conatiner my-5">
<h1>Text Summary</h1>
<p>Total Words {text.split(" ").length - 1} and Characters {text.length}</p>
<h3>preview</h3>
<p>{text}</p>
</div>
</>
)
}
2
Answers
While there probably is a solution for this way of doing this. I think the best solution is to just not do it that way.
You’re mixing different web-responsibilities togheter which only creates more Problems that you might wish. So my answer will be focusing on changing the way you achieve a dark mode, rather than focusing on why its not working like you want it to be (it will implicitly answer that part).
The Easiest Solution: Use CSS! Dark Mode is something (almost) entirely on the styling side. It has primarly nothing to do with JS or HTML (Only to toggle it).
Instead of toggling explicit styling in React, toggle a class. And in the class define the dark-mode-style. Why? Because you will solve so many redundancies. Right now you need to write code to change the Color of a background at every node basically. When you set a class at root-level of your app and maybe have a button that can change the state on that level… you never need to care about dark-mode-styling in your react-code, but only in a css file.
And you can grade this up. There are things called data-tags. And e.g. you can set a Data-tag "data-theme" on the html-tag and toggle it there (data-theme=dark, data-theme=light). Now extensions that e.g. force a dark mode in chrome will check for stuff like that and instead of creating a own dark mode, they toggle the intended dark mode.
And to give you a small example how i would suggest you change it:
Create a button somewhere in your app that can toggle the dark mode. Instead of having a state that you need to bleed through the whole app, toggle a data-tag on the html tag.
Create CSS-Files for your components where you handle ALL the style and differentiate between elements in a dark mode or light mode.
Example:
And there is even an easier way to do it, but i assume you dont know CSS so its maybe more confusing… But there are CSS-Variables and if you have a set Theme you can only use variables for colors and styling in general. And basically instead of changing css-rules when toggling a dark-mode, you can change the vars:
The main app file is simply missing the
mode
prop when rendering<TextForm heading="Enter text to analyze below"/>
.So, it should be: