Reputation: 31
I am new to React and trying to build a website with dark mode.
by changing the data-theme in CSS file when the toggle button is clicked, and the following is my file structure in App.jsx
.
├── Header
│ └── DarkModeToggle
├── Content
│
└── (CSS file)
DarkModeToggle.jsx
class NightModeToggle extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: 'light',
}
this.toggleTheme = this.toggleTheme.bind(this);
}
toggleTheme() {
const theme = this.state.theme === 'dark' ? 'light' : 'dark';
this.setState({ theme });
document.documentElement.setAttribute("data-theme", theme);
}
render() {...}
}
I also use react route so that I can display different information in different URL
Content.jsx
class Content extends React.Component {
render() {
return (
<div id="content">
<BrowserRouter>
<Switch>
<Route exact path='/test' component={Test}></Route>
<Route exact path='/home' component={Home}></Route>
<Route exact path='/project' component={Project}></Route>
</Switch>
</BrowserRouter>
</div>
);
}
}
However, the website cannot keep the theme when I go to other URL.
For example, I change to dark mode in /home
and then I go to /project
, the website will back to the light mode.
How can I maintain the theme
variable (or init a global variable) when I using React-Route? Thank you for your help!
Upvotes: 0
Views: 2427
Reputation: 1
I unfortunately don't have an answer for you because I'm dealing with the same problem even after taking advantage of the Context API. I created a routing layer that handles my path constants through a routing object, which then uses a layout component to produce an "outlet" element. I wrapped my entire app with my theme context provider and the same issue persists. The only thing I've been able to find to solve it is that the theme state could be stored in localStorage
and accessed upon rendering the theme context provider. I haven't tried it yet, because it seems like there's something wrong with the way I'm doing something, but I'll let you know if I find the fix on the way there.
EDIT: I've found an answer and the obviousness of it still pains me; I hope this is an answer for anyone will this same issue. All I needed to do was replace the anchor tags with Link tags. I presume you could probably prevent the default behavior of the anchors as well, but it seemed like better practice to just replace them with Link elements.
Upvotes: 0
Reputation: 164
You can use styled components for theming the web app.
Please refer this link for more info:
https://styled-components.com/docs/advanced#theming
Upvotes: 0
Reputation: 3978
You can use Context API from react
to create global context.
Then you can wrap your app file within context you have created.
Now you can access themeMode from any file inside react render tree.
Below is example, how you can use themeMode with context API
import React, { createContext, useState } from "react";
export const AppContext = createContext();
const AppProvider = ({ children }) => {
const [themeMode, setThemeMode] = useState("lightTheme");
const value = { themeMode };
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};
export default AppProvider;
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import AppProvider from "./AppProvider";
ReactDOM.render(
<AppProvider>
<App />
</AppProvider>,
document.getElementById("root")
import React, { useContext } from "react";
import { AppContext } from "./AppProvider";
const App = () => {
const { themeMode } = useContext(AppContext);
console.log("THEME MODE: ", themeMode);
return <div></div>;
};
export default App;
Upvotes: 2