javascript - react-spring - 在内容变化时为 <p> 元素设置动画

标签 javascript reactjs react-spring

以下代码是一个简单的 React 组件,它使用 react-springp (animated.p) 元素设置动画。动画在 fadeIn 常量中定义,并通过 style={fadeIn} 标签分配给 animated.p 元素。

//returns and animates <p> elements:
function QuoteBox(props) {
  const fadeIn = useSpring({ opacity: 1, from: { opacity: 0 } });
  return (
    <>
    <blockquote>
      <animated.p id="text" style={fadeIn}>{props.quote}</animated.p>
    </blockquote>
    <animated.p id="author" style={fadeIn}>{props.author}<cite><em>{props.from}</em></cite></animated.p>
    </>
  );
}

当页面加载并且 QuoteBox 组件安装到 DOM 中时,useSpringanimated.p 元素的不透明度从 0 更改为到 1。 但是,每次我将新的 props 传递给 animated.p 元素时,我都需要这样做,但我很难理解如何做到这一点。

有一些simple examples在 react-spring 文档页面上,它使用组件的 state (toggle) 将不透明度从 0 更改为 1,反之亦然,但不清楚我如何将不透明度从 0 更改为 1 每次 我将一个新的 prop 传递给 animated.p 元素。 我只是想在它改变时获得一个简单的文本淡入。

抱歉之前的困惑问题,这对我来说可能有点太难了。此外,我不完全确定 react-spring 是一个不错的选择,对于我想要实现的目标来说它似乎过于复杂。

最佳答案

您可以使用更新函数语法实现这一点。它使用返回初始属性的函数进行初始化,并返回允许覆盖初始属性的更新函数(以及 stop 函数,此处未使用):

function QuoteBox(props) {
  const [fadeIn, set] = useSpring(() => ({ opacity: 0 }));

  React.useEffect(() => {
    set({ opacity: 1, from: { opacity: 0 }});
  }, [set, props.quote, props.author, props.from]);

  return (
    <>
      <blockquote>
        <animated.p id="text" style={fadeIn}>
          {props.quote}
        </animated.p>
      </blockquote>
      <animated.p id="author" style={fadeIn}>
        {props.author}
        <cite>
          <em>{props.from}</em>
        </cite>
      </animated.p>
    </>
  );

这将有效地重置挂载时的动画以及 Prop 更改后的每个后续重新渲染。 React(或 ESlint)可能会提示 useEffect 的上述使用,因为实际上没有使用任何 prop 值,我们只是在观察它们的变化,因为它似乎暗示那是动画应该的时候重新运行。

您可以通过以下方式避免这种情况:

内存:

const MemoQuoteBox = React.memo(QuoteBox);

由于所有 props 都是字符串(一种简单的数据类型,按值相等,而不是像对象或数组那样按引用),您可以按原样内存组件,并且只有当其中一个更改时才会重新呈现。这将允许您删除依赖数组,因为现在组件只会在 prop 更改时更新:

React.useEffect(() => {
  set({ opacity: 1, from: { opacity: 0 }});
});

如果您将来要将更多 Prop 传递给此组件,则可能不太理想。

引用:

const currString = props.quote + props.author + props.from;
const prevString = React.useRef(currString);

React.useEffect(() => {
  if (currString === prevString.current) return;
  set({ opacity: 1, from: { opacity: 0 }});
  prevString.current = currString;
}, [set, currString]);

现在我们正在使用传递的值 ESlint 不应该抛出警告。我利用 props 都是字符串这一事实在此处将它们连接起来(因为它们在概念上是相关联的),但如果将它们分开,原理是相同的。

脏返回:

直接从 effect 返回值,ESlint 应该认为它们“已使用”,尽管此时您还不如使用 eslint-disable-next-line:

React.useEffect(() => {
  set({ opacity: 1, from: { opacity: 0 }});
  return props.quote + props.author + props.from;
}, [set, props.quote, props.author, props.from]);

关于javascript - react-spring - 在内容变化时为 <p> 元素设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67113669/

相关文章:

javascript - 在 maxlength-set 输入上粘贴时检测字符串长度

javascript - 有什么方法可以获取 "Allow"(chrome最新)中的 "Allow to use microphone popup"按钮点击事件吗?

javascript - 是否可以从我的页面获取另一个选项卡 url?

.htaccess - 使用 React 在 apache 上刷新页面不起作用

reactjs - 带有反应 Spring 动画的 react 三纤维

javascript - React spring过渡,实现每个元素的进入渐进式延迟

javascript - 标记过多时如何在谷歌地图上优化 MarkerWithLabel

ajax - react.js 和 Ajax 的区别

javascript - ReactJS - ref 返回 "undefined"

javascript - React Spring - 渲染之间的动画元素