【问题标题】:How to change the background of a styled.div if the window is scrolled to the top?如果窗口滚动到顶部,如何更改 styled.div 的背景?
【发布时间】:2021-09-16 07:41:16
【问题描述】:

如果窗口滚动到顶部,我想更改 div 的背景。我已经想出了如何在 React 中确定这一点,并且当 console.logging 我的 isAtTop 变量时,它会根据滚动而改变,但是实际的 div 似乎永远不会收到,因为 styled.div 不会改变颜色。我做了一个codePen:https://codesandbox.io/s/xenodochial-chebyshev-4poi3?file=/src/App.js

import "./styles.css";

import React from 'react'

import styled from 'styled-components'

export default function App() {
  let isAtTop = true;
  let bg = `linear-gradient(to right, #797cd2, #393e9e)`;

  function handleScroll() {
    isAtTop = window.scrollY === 0;

    isAtTop
      ? (bg = `linear-gradient(to right, #797cd2, #393e9e)`)
      : (bg = "white");
    console.log({ isAtTop });
  }

  React.useEffect(() => {
    console.log("UseEffect Run");
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  });

  const ColorChangeDiv = styled.div`
  background: ${bg};
  position: sticky;
  width: 100%;
  top: 0;
  height: 100px;
  `

  return (
    <>
    <ColorChangeDiv>
    {isAtTop.toString()} ? Hello my background should be {bg}
    </ColorChangeDiv>
    <div style={{height: '500rem'}}></div>
    </>
  );
}

【问题讨论】:

    标签: reactjs styled-components


    【解决方案1】:

    我对你的代码做了一点改动,现在我将解释具体更改了什么。

    1. 制作了功能箭头,看起来更干净
    2. 在 useCallback 中包装滚动事件处理程序以排除对 useEffect 的不必要调用,因为现在此函数处于 useEffect 依赖项中,最好指定 useEffect 中使用的所有依赖项。
    3. 背景颜色现在存储在状态中。您存储在一个变量中,组件不会在更改 let 变量时重新渲染。这意味着即使更改变量的值,组件也不会以新值显示自己。我们需要重新渲染。状态变化会导致重新渲染。这意味着如果您想根据更改的值更改组件,则将它们存储在一个状态中以调用重新渲染:)
    4. 我把styled组件拿出来了,看起来干净利落,而且放在APP组件里面没意义,可以在props中把值传给styled组件。看看下面的例子,现在背景是作为道具传递的
    5. 您有很长的默认背景值。它会重复自己。这么长重复的东西最好翻译成名字好理解的常量。看我把它命名为 DEFAULT_BG。

    https://codesandbox.io/s/boring-pasteur-18v0r?file=/src/App.js:361-372

    import React, { useCallback, useState, useEffect } from "react";
    import styled from "styled-components";
    
    const DEFAULT_BG = `linear-gradient(to right, #797cd2, #393e9e)`;
    
    const ColorChangeDiv = styled.div`
      background: ${(p) => p.bg};
      position: sticky;
      width: 100%;
      top: 0;
      height: 2000px;
    `;
    
    const App = () => {
      const [bg, setBg] = useState(DEFAULT_BG);
    
      const handleScroll = useCallback(() => {
        setBg(window.scrollY === 0 ? DEFAULT_BG : "white");
      }, []);
    
      useEffect(() => {
        window.addEventListener("scroll", handleScroll);
        return () => window.removeEventListener("scroll", handleScroll);
      }, [handleScroll]);
    
      return (
        <>
          <ColorChangeDiv bg={bg}>
            Hello my background should be {bg}
          </ColorChangeDiv>
          <div style={{ height: "500rem" }}></div>
        </>
      );
    };
    
    export default App;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多