简体   繁体   English

React - 从另一个组件切换主题

[英]React - Toggle theme from another component

I am working on a project on react but I have ran into an issue.我正在做一个关于反应的项目,但我遇到了一个问题。

The issue I am having is that I need to be able to toggle my "dark" and "light" theme from a icon that is in a different component.我遇到的问题是我需要能够从不同组件中的图标切换我的“深色”和“浅色”主题。 This icon exists in my BottomNavigation but the function for switching the theme exists in my app.js .此图标存在于我的BottomNavigation中,但用于切换主题的 function 存在于我的app.js中。

Did some research on my own and found that I need to "lift the state up".我自己做了一些研究,发现我需要“抬起 state”。 Issue is that I need to lift it twice as my files look like this:问题是我需要将它提升两次,因为我的文件如下所示:

./Components
  ./Home.js
    - (components gets added here)
  ./Navigation
    ./BottomNavigation.js

app.js
(/home is added here)

My app.js looks like:我的 app.js 看起来像:

function App() {
  const [theme, setTheme] = useState("light");

  const themeToggler = () => {
    theme === "light" ? setTheme("dark") : setTheme("light");
  };

  return (
    <ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
      <GlobalStyles />
      <Router>
        <Route exact path="/">
          <Home />
        </Route>
        <Route exact path="/account">
          <Account />
        </Route>
      </Router>
    </ThemeProvider>
  );
}

My Home.js looks like:我的 Home.js 看起来像:

const Home = (props) => {
  const [showingState, setIsShowing] = useState(false);

  return (
    <div>
      <TopNavigation isShowing={(showingState) => setIsShowing(showingState)} />
      <BottomNavigation />
      <ImageSlider />
      <Grid />
      {showingState && (
        <CurrencyPopup
          isShowing={(showingState) => setIsShowing(showingState)}
        />
      )}
      <BestSeller />
      <CollectionPromo />
      <Instagram />
      <Footer />
    </div>
  );
};

My BottomNavigation.js looks like (only took the part with the icon):我的 BottomNavigation.js 看起来像(只使用了图标的部分):

<div className={classes.options_container}>
  <IconApp className={classes.icon_container}>
    <span className={classes.cart_sum}>$0.00</span>
    <Cart className={classes.icon} />
  </IconApp>
  <IconApp className={classes.icon_container}>
    <Heart className={classes.icon} />
  </IconApp>
  <IconApp className={classes.icon_container}>
    <Visibility
      onClick={() => props.setTheme("")} //This icon shall switch the theme
      className={classes.icon}
    />
  </IconApp>
  <IconApp className={classes.icon_container}>
    <a href="/account">
      <User className={classes.icon} />
    </a>
  </IconApp>
</div>

If you have any ideas or need something more from the code, let me know!如果您有任何想法或需要代码中的更多内容,请告诉我!

For best practice, you have a few options:为了获得最佳实践,您有几个选择:

  1. Use React Context .使用反应上下文
  2. Use a state management library like Redux and MobX .使用 state 管理库,例如ReduxMobX

You definitely don't want to life state up in your case, because the two components are too far away from each other in the hierarchy.您绝对不想在您的情况下使用 state,因为这两个组件在层次结构中彼此相距太远。

Lifting state up would be solution that does not require any additional knowledge.提升 state 将是不需要任何额外知识的解决方案。 However, its excessive use (over three or more component) is a bad practice, since it makes code dirty但是,过度使用(超过三个或更多组件)是一种不好的做法,因为它会使代码变脏

Using RecoilJS would be easiest, since its api is nearly identical to that of useState , and there is less work for you to do使用 RecoilJS 是最简单的,因为它的useState与 useState 几乎相同,而且你要做的工作更少

Sticking to vanilla ReactJS, try React Context坚持原版 ReactJS,试试 React Context

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM