【发布时间】:2020-05-10 09:30:47
【问题描述】:
您好,我正在尝试在我的 react 应用中进行一些主题化。我有变量名current_theme 和名为changeTheme 的函数来更改父组件中的current_theme。我使用道具将current_theme 和chaneTheme 传递给我的子组件。在子组件中changeTheme 调用成功,但主题不会改变。我认为子组件不会在父组件中应用更改。当我使用 Redux 存储 current_theme 变量时没有问题,但我不想将 redux 与这个一起使用。我怎么解决这个问题? Header.tsx 是我的顶部导航栏,并且有切换主题的按钮。
App.tsx
import React from 'react';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import {IntlProvider} from 'react-intl';
import {ThemeProvider} from 'styled-components';
import {Layout} from 'antd';
import {Home, Search, Watch, NotFound} from '../pages';
import {Header, Footer} from '../components';
import Messages from '../locale/Messages';
import Config from './Config';
import {themes} from '../themes';
import {Theme} from '../themes';
import "./App.scss";
const App:React.FC = () => {
let current_theme:Theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
let theme = themes[current_theme];
const changeTheme = () => {
current_theme = current_theme == 'light' ? 'dark' : 'light';
theme = themes[current_theme];
console.log(theme);
}
return (
<Router>
<IntlProvider locale={Config.current_locale} messages={Messages[Config.current_locale]}>
<ThemeProvider theme={theme}>
<Layout id="wrapper">
<Header changeTheme={changeTheme} />
<Switch>
<Route exact path={Config.base_url} component={Home} />
<Route path={`${Config.base_url}/search/:keyword`} component={Search} />
<Route path={`${Config.base_url}/watch`} component={Watch} />
<Route path={`${Config.base_url}/watch/:id`} component={Watch} />
<Route component={NotFound} />
</Switch>
<Footer />
</Layout>
</ThemeProvider>
</IntlProvider>
</Router>
);
}
export default App;
Header.tsx
import React, {useState, useContext} from 'react';
import {Link} from 'react-router-dom';
import {useIntl} from 'react-intl';
import styled, {ThemeContext} from 'styled-components';
import {Layout, Menu} from 'antd';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faAdjust} from '@fortawesome/free-solid-svg-icons';
import Config from '../common/Config';
import './Header.scss';
type HeaderProp = {
changeTheme:VoidFunction|undefined
};
const Header:React.FC<HeaderProp> = (props) => {
const locale_names = require('../locale/locales.json');
const home = Config.base_url;
const intl = useIntl();
const [current, setCurrent] = useState<string>('');
const current_theme = useContext(ThemeContext);
const changeTheme = () => {
if (props.changeTheme)
props.changeTheme();
}
const handleClick = (event:any) => {
setCurrent(event && event.key);
}
return (
<HeaderDiv>
<Logo to={home}>{intl.messages.title}</Logo>
<TopMenu mode="horizontal" onClick={handleClick} selectable={false}>
<Menu.Item key="home"><Link to={home}>{intl.messages.home}</Link></Menu.Item>
<Menu.Item key="theme"><Link to="#" onClick={changeTheme}><FontAwesomeIcon icon={faAdjust} rotation={180} fixedWidth /></Link></Menu.Item>
</TopMenu>
</HeaderDiv>
);
}
const HeaderDiv = styled.div`
`;
const Logo = styled(Link)`
text-align: center;
vertical-align: middle;
width: 200px;
height: 100%;
float: left;
color: ${props => props.theme.font_color}
`;
const TopMenu = styled(Menu)`
height: 100%;
float: right;
vertical-align: middle;
a {
display: block;
height: 100%;
}
`;
export default Header;
【问题讨论】:
标签: reactjs