【问题标题】:React - How to apply multiple values from an object using contextReact - 如何使用上下文从对象中应用多个值
【发布时间】:2021-04-29 20:52:15
【问题描述】:

为此,我在我的项目中使用了一个颜色主题,我使用了一个 React 上下文来传递几个组件中的值,一切对我来说都很好,直到我决定在对象中添加另一个属性以便将不同的颜色应用于不同的组件,例如将绿色作为值的ThemeBackground 属性将应用于RoutesPage 组件,而将橙色应用于SideBar 组件的侧属性。问题是我无法为SideBar 组件应用side 属性,我尝试了几个选项,但我现在没有成功,我将在图片中更详细地向您展示所有内容,以便您清楚地了解问题然后我会给你代码

请注意 ThemesBackground 属性已成功应用于内容,但问题是我想在我为边栏导入 ThemeBackground 属性时将 side 属性应用到边栏,所以我的边栏应用红色颜色,但我认为您已经理解了短属性ThemeBackground 应该应用于内容和side 属性到侧边栏的问题

LessonThemes.jsx

import React, { useState, useEffect, createContext } from "react";
import SideBar from "./SideBar";
import RoutesPage from "../pages/Routes";

export const CounterContext = createContext(["color"]);


export default function LessonThemes(props) {
    const [BackgroundTheme, SetBackgroundTheme] = useState(localStorage.getItem("color"));

    const [themes, setThemes] = useState([
        { name: "G", ThemeBackground: "maroon", side: "orange" },
        { name: "R", ThemeBackground: "red", side: "aqua"  },
        { name: "B", ThemeBackground: "blue", side: "pink"  },
    ])

    useEffect(() => {
        localStorage.setItem("color", BackgroundTheme);
    })

    const SideBarPageContent = (SideBarPageContentBackground) => {
        localStorage.setItem('color', SideBarPageContentBackground);
        SetBackgroundTheme(SideBarPageContentBackground);
    }

    const list = themes.map((theme, index) => {
        return (
            <label key={index}>
                <input
                    onChange={() => SideBarPageContent(theme.ThemeBackground)}
                    type="radio"
                    name="background"
                />{theme.name}</label>
        );
    })

    return (
        <CounterContext.Provider value={[BackgroundTheme, SetBackgroundTheme]}>
            <SideBar list={list} {...props} />
            <RoutesPage path={props.match} />
        </CounterContext.Provider>
    );
}

SideBar.jsx

import React from 'react';
import {CounterContext} from "./LessonThemes";
import SideBarMenu from "./SideBarMenu";
import '../css/Sidebar.css'

export default function SideBar(props) {
    const [BackgroundTheme, SetBackgroundTheme] = React.useContext(CounterContext);
    return (
        <div className="wrappers">
            <nav id="sidebar" className="sidebar-wrapper modal">
                <div style={{background: BackgroundTheme}} className={"sidebar-page-content"}>
                    <div className="sidebar-brand">
                        <div className="sidebar-brand-container">
                            <div>
                                {props.list}
                            </div>
                            <div>
                                <span href="#">Theme</span>
                            </div>
                        </div>
                    </div>

                    <div className="sidebar-menu">
                        <SideBarMenu path={props.match.path}/>
                    </div>

                    ...
                </div>
            </nav>
        </div>
    );
}

不知道对你有用没

RoutesPage.jsx

import React from "react";
import {Route, Switch} from "react-router-dom";
import '../css/Sidebar.css'
import {CounterContext} from "../components/LessonThemes";

function RoutesPage(props) {
    const {path} = props.path;

    const routes = [
        {
            path: `${path}`,
            exact: true,
            component: () => <h2>Home</h2>
        },
        {
            path: `${path}/Calendar`,
            component: () => <h2>Test123</h2>
        },
        {
            path: `${path}/Guardian`,
            component: () => <h2>Shoelaces</h2>
        }
    ];
    const [BackgroundTheme, SetBackgroundTheme] = React.useContext(CounterContext);

    return (
        <>
            <main style={{background: BackgroundTheme}} className="page-content">
                <div className="page-container">
                    <h2>Pro Sidebar</h2>
                    <hr/>
                    <div className="tabs">
                        <Switch>
                            {routes.map((route, index) => (
                                <Route
                                    key={index}
                                    path={route.path}
                                    exact={route.exact}
                                    component={route.component}
                                />
                            ))}
                        </Switch>
                    </div>
                </div>
            </main>
        </>
    );
}

export default RoutesPage;

【问题讨论】:

    标签: javascript reactjs ecmascript-6 react-hooks react-context


    【解决方案1】:

    是否可能在 SideBar.jsx 中,div 样式需要设置为 BackgroundTheme 而不是 SideBarBackgroundTheme?它也不会传入对象,因此您仍然需要键入特定颜色的键吗?喜欢 BackgroundTheme.side?​​p>

    【讨论】:

      【解决方案2】:

      问题是side 属性永远不会存储到上下文的value 中。您的上下文值仍然只是 string。存在的完整主题对象只是LessonThemes 组件的本地状态。

      inputonChange 处理程序中,您调用SideBarPageContent,后者又调用SetBackgroundTheme,这会更新您传递给上下文提供程序的BackgroundTheme 属性。您传递给此函数调用的参数是theme.ThemeBackground——它只是背景颜色,而不是整个对象。

      您可能希望重构代码,以便上下文包含整个对象。

      SideBar 组件中,不清楚您认为变量SideBarBackgroundTheme 来自何处,但该变量不存在。

      【讨论】:

      • 在我问这个问题之前这是我的错,我尝试了几个选项并忘记更改 SideBarBackgroundTheme 而不是这个现在应该是 BackgroundTheme 我当然编辑了我的问题但是问题没有解决
      • 你明白这个问题吗?您的上下文只是一种颜色,而不是具有多种颜色的对象?
      • 我能够解决这个问题,我会尽快回答我的问题
      【解决方案3】:

      LessonThemes.jsx

      import React, {useState, useEffect, createContext} from "react";
      import SideBar from "./SideBar";
      import RoutesPage from "../pages/Routes";
      
      export const CounterContext = createContext([]);
      
      
      export default function LessonThemes(props) {
          const [SideBarTheme, SetSideBarTheme] = useState(localStorage.getItem("SideBarKey"));
          const [PageContentTheme, SetPageContentTheme] = useState(localStorage.getItem("PageContentKey"));
      
          const [themes, setThemes] = useState([
              {
                  name: "G",
                  SideBar: "maroon",
                  PageContent: "blue",
              },
              {
                  name: "R",
                  SideBar: "gray",
                  PageContent: "green",
              },
          ])
      
          useEffect(() => {
              localStorage.setItem("SideBarKey", SideBarTheme, "PageContentKey", PageContentTheme);
          })
      
          const SideBarPageContent = (PageContent, SideBar) => {
              localStorage.setItem('PageContentKey', PageContent, 'SideBarKey', SideBar);
              SetPageContentTheme(PageContent);
              SetSideBarTheme(SideBar);
          }
      
          const list = themes.map((theme, index) => {
              return (
                  <label key={index}>
                      <input
                          onChange={() => SideBarPageContent(theme.PageContent, theme.SideBar)}
                          type="radio"
                          name="background"
                      />{theme.name}</label>
              );
          })
      
          return (
              <CounterContext.Provider value={{
                  SideBarValue: [SideBarTheme, SetSideBarTheme],
                  PageContentValue: [PageContentTheme, SetPageContentTheme]
              }}>
                  <SideBar list={list} {...props} />
                  <RoutesPage path={props.match}/>
              </CounterContext.Provider>
          );
      }
      

      SideBar.jsx

      export default function SideBar(props) {
      
          const { SideBarValue } = React.useContext(CounterContext);
          const [SideBarTheme, SetSideBarTheme] = SideBarValue;
      
          return (
              <div className="wrappers">
                  <nav id="sidebar" className="sidebar-wrapper modal">
                      <div style={{background: SideBarTheme}} className={"sidebar-page-content"}>
                          <div className="sidebar-brand">
                              <div className="sidebar-brand-container">
                                  <div>
                                      {props.list}
                                  </div>
                                  <div>
                                      <span href="#">Theme</span>
                                  </div>
                              </div>
      ...
      

      RoutesPage.jsx

      import React from "react";
      import {Route, Switch} from "react-router-dom";
      import '../css/Sidebar.css'
      import {CounterContext} from "../components/LessonThemes";
      
      function RoutesPage(props) {
          const {path} = props.path;
      
          const routes = [
              {
                  path: `${path}`,
                  exact: true,
                  component: () => <h2>Home</h2>
              },
              {
                  path: `${path}/Calendar`,
                  component: () => <h2>Test123</h2>
              },
              {
                  path: `${path}/Guardian`,
                  component: () => <h2>Shoelaces</h2>
              }
          ];
      
          const { PageContentValue } = React.useContext(CounterContext);
          const [PageContentTheme, SetPageContentTheme] = PageContentValue;
      
          return (
              <>
                  <main style={{background: PageContentTheme}} className="page-content">
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-14
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 1970-01-01
        相关资源
        最近更新 更多