【问题标题】:How can I detect prop modified from parent component?如何检测从父组件修改的道具?
【发布时间】:2020-05-10 09:30:47
【问题描述】:

您好,我正在尝试在我的 react 应用中进行一些主题化。我有变量名current_theme 和名为changeTheme 的函数来更改父组件中的current_theme。我使用道具将current_themechaneTheme 传递给我的子组件。在子组件中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


    【解决方案1】:

    我是 reactjs 新手,所以我犯了一个愚蠢的错误。我将current_theme 声明为变量,但如果我将current_theme 声明为更新状态,它会重新渲染。所以答案是使用状态。

    【讨论】:

      猜你喜欢
      • 2014-10-09
      • 1970-01-01
      • 2018-08-06
      • 2015-08-29
      • 1970-01-01
      • 2019-11-14
      • 2018-04-21
      • 1970-01-01
      • 2020-07-30
      相关资源
      最近更新 更多