javascript - 意外行为 : function vs functional component and animations

标签 javascript reactjs

我显示了一个 foos 列表,当我点击某个链接时 更多结果 我保留了现有的 foos 并向它们附加了来 self 的 api 的新结果,如下所示

const [foos, setFoos] = useState([]);
...
// api call with axios
...
success: (data) => {
    setFoos([ ...foos, ...data ])
},

每个<Foo />组件运行上面的动画

App.js

...
<div className="foos-results">
    { foos.map((foo, index) => <Foo {...{ foo, index }} key={foo.id}/>) }
</div>
...

Foo.js

const Foo = ({ foo, index }) => <div className="circle">...</div>

动画.css

.circle {
   ...
   animation: progress .5s ease-out forwards;
}

问题是当我附加新的时,<Foo /> 的所有行都会触发动画。 .

预期的行为是仅针对新动画触发动画,而不是从现有动画开始。

更新

我们找到了问题的根源(与key={foo.id}的唯一性无关)

如果我们改变

const Foo = ({ foo, index }) => <div className="circle">...</div>

const renderFoo = ({ foo, index }) => <div className="circle">...</div>

和 App.js 到

...
<div className="foos-results">
    { foos.map((foo, index) => renderFoo({ foo, index })) }
</div>
...

有效

那么为什么这种行为在 react 中是这样的呢?

这是一个sandbox基于@Jackyef 代码

最佳答案

这是一个非常有趣的问题。

让我们看看sandbox问题中提供。

内部App ,我们可以看到这一点。

  const renderItems = () => (
    <div>
      {items.map((item, index) => (
        <div className="item" key={item.id}>
          <span>
            {index + 1}. {item.value}
          </span>
        </div>
      ))}
    </div>
  );

  const Items = () => renderItems();

  return (
    <div className="App">
      <h1>List of items</h1>
      <button onClick={addItem}>Add new item</button>
      <Items />
    </div>
  );

看起来很无害吧?问题在于 ItemsApp 中声明渲染功能。这意味着在每次渲染时,Items实际上现在是一个不同的函数,尽管它的作用是一样的。

<Items />被翻译成 React.createElement ,并且在比较时,React 会考虑每个组件的引用相等性来决定它是否与先前渲染的组件相同。如果不相同,React 会认为它是一个不同的组件,如果不同,它只会创建并挂载一个新组件。这就是您看到动画再次播放的原因。

如果声明Items App 之外的组件像这样:

const Items = ({ items }) => (
  <div>
    {items.map((item, index) => (
      <div className="item" key={item.id}>
        <span>
          {index + 1}. {item.value}
        </span>
      </div>
    ))}
  </div>
);

function App() { /* App render function */}

您会看到一切都按预期进行。 Sandbox here

总结一下:

  1. 差异时引用相等性对 React 很重要
  2. 组件(返回 JSX 的函数或类)应该是稳定的。如果它们在渲染之间发生变化,React 将因第 1 点而遇到困难。

关于javascript - 意外行为 : function vs functional component and animations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58829050/

相关文章:

javascript - 使用从 jquery 传递到 php 的变量动态更新字段

javascript - 如何重载比较器以使用 UTF-8 和不同的语言环境进行排序

javascript - 几个值中的最小值,不得为 0

javascript - 优化 React 代码

javascript - DraftJs:使用实体键替换实体

javascript - React Child componentDidMount 没有在 Route 上触发

javascript - JSSOR slider 不适用于动态数据

javascript - React-select 不渲染数据

javascript - 在 React 中渲染嵌套导航

javascript - 设置初始状态以避免错误 : "can not read property of undefined"? 的最佳方法是什么