Improving Light and Dark Mode
In this Article, we
improve the previously implemented dark and light mode by applying it to the entire React application
instead of a single component. We also refactor the App component to manage theme state efficiently and
pass it to child components using props. This approach helps beginners understand better code structure
and reusability in React.js.
Features of the Updated React State Code
Features of This Improved Dark Mode Project
Full application light and dark mode implementation in React.js
Centralized theme control inside the App component
Clean and refactored code structure for better readability
Theme state passed to child components using props
Background color changes dynamically without page reload
Beginner-friendly React project with real-world use case
Why This Refactoring is Important?
Keeps theme logic in one place,
Makes components clean and reusable,
Follows React best practices,
Easy to extend with more themes in the future,
App.JS Code:-
import { useState } from 'react';
import './App.css';
// import About from './components/About';
import Navbar from './components/Navbar';
import TestForm from './components/TestForm';
function App() {
const[mode, setmode] = useState('dark')
let togglemode=()=>{
if(mode === 'light'){
setmode('dark')
document.body.style.backgroundColor = 'black';
} else{
setmode('light')
document.body.style.backgroundColor = 'white';
}
}
return (
<>
<Navbar
name="Royal Coding Text"
about_us="About us Text"
mode={mode}
togglemode={togglemode}
/>
<TestForm
heading="Enter the Text to use below Features"
mode={mode}
/>
{/* <About/> */}
</>
);
}
export default App;
TestForm.JS Code:-
import React, { useState } from "react";
export default function TestForm(props) {
const [text, newText] = useState("");
const handleUpCase = () => {
newText(text.toUpperCase());
};
const handleLowCase = () => {
newText(text.toLowerCase());
};
const handleClear = () => {
newText("");
};
const handleCopy = () => {
if (navigator.clipboard) {
navigator.clipboard.writeText(text);
} else {
alert("Clipboard not supported");
}
};
const handleExtraSpaces = () => {
newText(text.split(/\s+/).join(" "));
};
const handleChange = (event) => {
newText(event.target.value);
};
const wordCount = text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
return (
<>
<div
className="container"
style={{ color: props.mode === "light" ? "black" : "white" }}
>
<h1 className="my-3 py-2">{props.heading}</h1>
<textarea
className="form-control mb-3"
style={{
backgroundColor: props.mode === "light" ? "white" : "#212529",
color: props.mode === "light" ? "black" : "white",
}}
value={text}
onChange={handleChange}
rows="8"
></textarea>
<button className="btn btn-primary mx-1" onClick={handleUpCase}>
Uppercase
</button>
<button className="btn btn-success mx-1" onClick={handleLowCase}>
Lowercase
</button>
<button className="btn btn-warning mx-1" onClick={handleExtraSpaces}>
Remove Spaces
</button>
<button className="btn btn-info mx-1" onClick={handleCopy}>
Copy Text
</button>
<button className="btn btn-danger mx-1" onClick={handleClear}>
Clear
</button>
<div className="my-3">
<p>
<strong>Words:</strong> {wordCount} |
<strong> Characters:</strong> {text.length}
</p>
</div>
<div className="my-3">
<h3>Preview</h3>
<p>{text.length > 0 ? text : "Nothing to preview..."}</p>
</div>
</div>
</>
);
}
Navbar.JS Code:-
import React from "react";
export default function Navbar(props) {
return (
<>
<nav
className={`navbar navbar-expand-lg navbar-${props.mode} bg-${props.mode}`}
>
{" "}
{/* Template Literal Expression= ${} */}
<div className="container-fluid">
<a className="navbar-brand" href="/">
{props.name}
</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="/">
{props.about_us}
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/">
Contact us
</a>
</li>
</ul>
<div
className={`form-check form-switch text-${
props.mode === "light" ? "dark" : "light"
}`}
>
<input
className="form-check-input"
type="checkbox"
onClick={props.togglemode}
role="switch"
id="switchCheckDefault"
/>
<label className="form-check-label" htmlFor="switchCheckDefault">
Enable Dark Mode
</label>
</div>
</div>
</div>
</nav>
</>
);
}