更新功能组件道具不会改变样式

Updating functional component props doesn't change styling

我有这个功能组件用于将跨度渲染为条形图。当我渲染组件时,我将道具 scrolled 作为 false 传递。然后,当我滚动 150 像素时,jQuery 将属性更新为 true。我知道使用 jQuery 不是好的做法,我正在从它迁移。现在,我想让它工作,因为我还在学习功能组件。

export default function Button(props) {
  const [scrolled, setScrolled] = useState( props.scrolled );
  useEffect(() => {
    setScrolled(props.scrolled);
  }, [scrolled]);

  return (
    <HamburgerButton scrolled={scrolled}>
      <p>{scrolled}</p> 
      <span></span>
    </HamburgerButton>
  );
}

这个样式化的组件定义:

const HamburgerButton = styled.div`
  ...
  span {
        background: ${props => props.scrolled === 'false' ? props.theme.white : props.theme.black};
  }
  ...
`;

滚动时,我看到 DOM 中的属性 scrolled 从 'false' 更改为 'true',但跨度保持白色。此外,带有 {scrolled} 的段落标记不会从 false.

更改

问题 您的代码记住了挂钩中的 props.scrolled 值。

export default function Button(props) {
  const [scrolled, setScrolled] = useState( props.scrolled ); // state initialized
  useEffect(() => { // hook called first render
    setScrolled(props.scrolled); // state updated with same value
  }, [scrolled]); // state value never changes during life of component so effect hook never recomputes

  return (
    <HamburgerButton scrolled={scrolled}>
      <p>{scrolled}</p> 
      <span></span>
    </HamburgerButton>
  );
}

解决方法 您可以直接将 prop 传递给 HamburgerButton

export default function Button(props) {
  return (
    <HamburgerButton scrolled={props.scrolled}>
      <p>{props.scrolled}</p> 
      <span></span>
    </HamburgerButton>
  );
}

或者使用钩子并使用正确的依赖关系

export default function Button(props) {
  const [scrolled, setScrolled] = useState( props.scrolled );
  useEffect(() => {
    setScrolled(props.scrolled); // update state
  }, [props.scrolled]); // with the value that changes here

  return (
    <HamburgerButton scrolled={scrolled}>
      <p>{scrolled}</p> 
      <span></span>
    </HamburgerButton>
  );
}

对三元的真实分支使用正比较并利用 javascript 的 truthy/falsey 值。如果 scrolledtrue 或任何其他真值,则呈现黑色,如果 fasley,则 (false, 0, null, undefined) 呈现白色。

const HamburgerButton = styled.div`
  ...
  span {
    background: ${props => props.scrolled ? props.theme.black : props.theme.white};
  }
  ...
`;

const HamburgerButton = styled.div`
  ...
  span {
    background: ${props => props.theme[props.scrolled ? 'black' : 'white']};
  }
  ...
`;