【问题标题】:Triggering useState触发 useState
【发布时间】:2020-05-01 23:30:47
【问题描述】:

我有一个组件并使用不同的道具有条件地渲染它。

      {activeNavItem === 'Concept Art' ? (
        <Gallary
          images={conceptArtImages}
          sectionRef={sectionRef}
        />
      ) : (
        <Gallary
          images={mattePaintingImages}
          sectionRef={sectionRef}
        />
      )}

这个组件有useState(false)useEffect 钩子。 useEffect 确定屏幕位置何时到达 dom 元素并触发 useStatetrue: elementPosition &lt; screenPosition。然后我的state 在 dom 元素上触发类:state ? 'animationClass' : ''

const Gallary = ({ images, sectionRef }) => {
  const [isViewed, setIsViewed] = useState(false);

  useEffect(() => {
    const section = sectionRef.current;

    const onScroll = () => {
      const screenPosition = window.innerHeight / 2;
      const sectionPosition = section.getBoundingClientRect().top;
      console.log(screenPosition);

      if (sectionPosition < screenPosition) setIsViewed(true);
    };

    onScroll();
    window.addEventListener('scroll', onScroll);

    return () => {
      window.removeEventListener('scroll', onScroll);
    };
  }, [sectionRef]);

  return (
    <ul className="section-gallary__list">
      {images.map((art, index) => (
        <li
          key={index}
          className={`section-gallary__item ${isViewed ? 'animation--view' : ''}`}>
          <img className="section-gallary__img" src={art} alt="concept art" />
        </li>
      ))}
    </ul>
  );
};

问题:它适用于我的第一次渲染。但是当我使用不同的道具切换组件时,我的 state 最初是 true 并且我没有动画。

我注意到如果我有两个组件(ComponentA, ComponentB)而不是一个(ComponentA),它可以正常工作。

【问题讨论】:

  • 请附上组件的代码。阅读代码比从描述中重构代码更容易。
  • @OriDrori 更新
  • @nukuutos 你的意思是当你第二次更改activeNavItem 时它不会动画??
  • @adel 是的,你是对的
  • 我注意到您应该使用setIsViewed(true) 而不是setIsViewed(() =&gt; true)

标签: javascript reactjs react-hooks


【解决方案1】:

当您的组件不在视图中时,尝试将 isViewed 设置为 false,如下所示:

if (sectionPosition < screenPosition && !isViewed){
setIsViewed(true);
}
else{
if(isViewed) 
   setIsViewed(false);
}

你可以这样做:

if (sectionPosition < screenPosition && !isViewed){
setIsViewed(state=>!state);
}
else{
if(isViewed) 
   setIsViewed(state=>!state);
}

加上不需要多次渲染同一个组件,你可以只改变道具:

  <Gallary
      images={activeNavItem === 'ConceptArt'?conceptArtImages:mattePaintingImages}
      sectionRef={sectionRef}
    />

【讨论】:

  • 它不工作。它通过screenPosition 取消课程,而不是通过具有不同道具的渲染组件。
  • 如果您的组件在视图中,那么不会尝试添加动画类???
  • 一旦在视图中动画类必须留下。当组件更改时,它必须取消动画类并在screenPosition 达到elementPosition 时添加它
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2020-03-22
相关资源
最近更新 更多