簡體   English   中英

更改 reactJS 中 hover 上的父組件背景

[英]Change parent component background on hover in reactJS

我有以下反應代碼

代碼

我想要的是當我 hover 我的“電子商務”圖片應用程序組件背景應該在“電子商務”圖片背景上更改。

所以分別和其他圖片。

如果您能幫我解決這個問題,我將不勝感激。

解決問題的兩種方法。 一個是傳遞一個 function 來更新 state,另一個是使用上下文。 在這種情況下,使用上下文是有意義的,因為您正在通過多個不關心 function 的組件傳遞 function。

首先要做的是使背景圖像在 div 的樣式中動態化並使用上下文:

// Put this outside the component
export const BackgroundContext = React.createContext(null);

// -- snip
const [backgroundImage, setBackgroundImage] = useState(Ecommerce);
const updateBackgroundImage = newImage => setBackgroundImage(newImage);

// -- snip
<BackgroundContext.Provider value={updateBackgroundImage}>
  <div className="App" style={{ backgroundImage: `url(${backgroundImage})` }}>
  {/* -- snip */}
</BackgroundContext.Provider>

現在在您的SolutionsSectionBoxItem組件中,您可以導入背景上下文:

import BackgroundContext from "../App";

然后使用該上下文並將反應的鼠標懸停在 api 上,更新選定的背景圖像:

  const setBackgroundImage = useContext(BackgroundContext);
  // -- snip
  <img onMouseOver={() => setBackgroundImage(solutionIMG)} {/* -- snip -- */} />

你可以在這里閱讀更多: https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down

根據 React 文檔,上下文應僅用於真正的全局 state,如當前用戶或主題。 對組件使用上下文會降低它們的可重用性

更新代碼

你的組件樹是 App -> SolutionBox -> SolutionItem。

您想對 App 中的 SolutionItem 中的事件“做出反應”,但它們之間有 SolutionBox,因此您必須通過 SolutionBox 將事件線程化到 App。

步驟1

為在 OnHover 上調用的 SolutionItem 添加一個道具,這將是一個 function 回調,任何父組件都可以使用它來對更改做出反應。

function SolutionsSectionBoxItem({ solutionIMG, onHover }) {
  let callOnHover = state => {
    if (_.isFunction(onHover)) {
      onHover(state);
    }
  };

  return (
    <div className="solutions-section-item-box">
      <img
        src={solutionIMG}
        alt=""
        onMouseEnter={() => {
          callOnHover(true);
        }}
        onMouseLeave={() => {
          callOnHover(false);
        }}
        className="solutions-section-item-img"
      />
    </div>
  );
}

第2步

在 BGChanged 上添加一個名為 SolutionBoxItem 的道具,這將再次成為 function 回調,當任何解決方案項懸停時都會調用該回調。 此 function 將采用 menuName 字符串並傳遞當前菜單名稱或默認值。

function SolutionsSectionBox({ onBGChanged }) {
  let callBGChanged = menuName => {
    if (_.isFunction(onBGChanged)) {
      onBGChanged(menuName);
    }
  };

  return (
    <div className="solutions-section-box-box">
      <SolutionItem
        solutionIMG={Ecommerce}
        onHover={state => {
          callBGChanged(state === true ? "Ecommerce" : "default");
        }}
      />
      <SolutionItem
        solutionIMG={SalesMarketing}
        onHover={state => {
          callBGChanged(state === true ? "SalesMarketing" : "default");
        }}
      />
      <SolutionItem
        solutionIMG={Analytics}
        onHover={state => {
          callBGChanged(state === true ? "Analytics" : "default");
        }}
      />
      <SolutionItem
        solutionIMG={Middleware}
        onHover={state => {
          callBGChanged(state === true ? "Middleware" : "default");
        }}
      />
    </div>
  );
}

第 3 步

在 App 組件中監聽更改。 在這里,我們現在在鼠標進入或離開解決方案項目時設置 state。 From here you have to change the background, you are using css to control the background url, this will be harder since you now need css class for each background type. 您可以使用 bgImage state 值來更改額外 css 類名的名稱,例如“AppSalesMarketing”、“AppEcommerce”等。

    export default function App() {
  const [bgImage, setbgImage] = useState(E);

  const onBGChanged = menuName => {
    setbgImage(menuName);
  };

  return (
    <div className={`App ${bgImage === "default" ? "" : `App${bgImage}`}`}>
      <SolutionBox onBGChanged={onBGChanged} />
    </div>
  );
}

在 CSS

保留原來的 App class 但基於 bgImage 值添加一個額外的使用 bgImage + App 的名稱,如下所示,以級聯更新的背景圖像值。

.AppEcommerce {
  background-image: url(https://placekitten.com/600/600);
}

.AppSalesMarketing {
  background-image: url(https://placekitten.com/500/800);
}

.AppAnalytics {
  background-image: url(https://placekitten.com/800/500);
}

.AppMiddleware {
  background-image: url(https://placekitten.com/700/700);
}

額外的

我在調用之前添加了 lodash 來測試傳入的 props 是函數,做防御性編程很好,因為你永遠不知道將來誰會使用你的組件。

let callBGChanged = menuName => {
    if (_.isFunction(onBGChanged)) {
      onBGChanged(menuName);
    }
  };  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM