简介
这篇文章展示了一种使用React的useContext 和useState 钩子来实现黑暗/光明模式切换的方法。相关文件是:src/ThemeProvider.tsx,src/index.tsx, 和src/App.tsx 。
这个项目使用了Typescript,但同样的功能也可以在javascript中通过移除类型来实现。
深入了解代码
ThemeProvider.tsx
在我们的ThemeProvider 组件中,我们将我们的Theme 定义为浅色或深色,我们将我们的ThemeContext 定义为一个具有两个属性的对象:theme 和toggleTheme (主题和切换主题的能力将通过useContext 钩子提供给其他组件)。
我们必须确保使用React.createContext ,导出我们创建的ThemeContext 对象。
在ThemeProvider 组件中,我们使用useState 钩子维护我们的theme 状态,并创建一个toggleTheme 函数,在light 和dark 之间切换状态。
为了简单起见,我们根据当前theme 的状态是亮还是暗,简单地设置文档主体的color 和backgroundColor 样式。最后,我们导出我们的ThemeContext Provider ,并将其值设置为与theme 和toggleTheme 属性的对象。然后我们在我们的ThemeContext.Provider 组件中渲染children 。
import React, { useState } from "react";
typescript;
type Theme = "light" | "dark";
type ThemeContext = { theme: Theme; toggleTheme: () => void };
export const ThemeContext = React.createContext<ThemeContext>(
{} as ThemeContext
);
export const ThemeProvider: React.FC = ({ children }) => {
const [theme, setTheme] = useState<Theme>("light");
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
const color = theme === "light" ? "#333" : "#FFF";
const backgroundColor = theme === "light" ? "#FFF" : "#333";
document.body.style.color = color;
document.body.style.backgroundColor = backgroundColor;
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
index.tsx
在我们的index 文件中,我们简单地将整个应用程序包裹在我们新的ThemeProvider 组件中。当然,在实际项目中我们不需要在应用程序层面上这样做,我们只需要确保任何需要theme 或toggleTheme 的组件都在我们提供者的子树中。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ThemeProvider } from './ThemeProvider';
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);
App.tsx
在App 组件中,我们使用useContext 钩子来访问我们的theme 字符串和toggleTheme 函数。我们创建了一个简单的按钮,可以切换主题,只使用theme 来决定我们向用户展示什么。"切换到黑暗模式 "或 "切换到光明模式"
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeProvider';
const App: React.FC = () => {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<div>
<div>Hi friend!</div>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
</div>
);
};
export default App;
就这样了!