在使用react-transition-group

时间:2019-06-25 14:24:32

标签: javascript reactjs gatsby react-transition-group

在我正在从事的gatsby项目中使用react-transition-group软件包时,我注意到了这种现象。我有一个“标签”列表,这些标签是从另一个主列表中选取的,它们被添加到活动列表中。单击主列表中的标签将其添加到活动列表中,然后单击活动列表中的标签将其删除。您几乎希望这样的事情起作用。

in 过渡很好用,但是当 out 过渡时,标签以一种奇怪的方式重新组织。我们有五个具有以下值的标记:

  • 免费乳制品
  • 派对食品
  • 家庭大小
  • 低胆固醇
  • 低钠

如果单击Family Sized标记将其删除,则会发生以下情况:

  1. Family Sized立即消失
  2. Low CholesterolLow Sodium立即向左移动
  3. 最后一个标签立即更改为Low Sodium
  4. 最后一个标签,现在具有Low Sodium的值了

预期的行为是Family Sized标签从其在组中间的位置过渡出来。我应该注意,如果您从活动列表中删除 last 标记,效果会很好,这仅在从任何其他位置删除标记时才会发生。

这是过渡的slowed-down GIF,这是我的代码:

<TransitionGroup className='tag-container'>
  {filter.map((tag, index) => {
    return (
      <CSSTransition key={index} timeout={250} classNames={`tag`}>
        <TagButton value={tag} onClick={onClickFunction} className={`${screenStyle} active`}>{tag}</TagButton>
      </CSSTransition>
    )
  })}
</TransitionGroup>
  • filter是从组件状态解构的数组。
  • 重要的是,在组件的同一<StaticQuery>方法中使用了gatsby中的render()
  • <TagButton>是来自styled-components包的样式化组件,而不是单独导入的组件。

2 个答案:

答案 0 :(得分:7)

在数组中添加特定的标识符并将每个元素的键设置为map方法中的每个标识符将解决您的问题。

import React from "react";
import ReactDOM from "react-dom";
import { Button } from "react-bootstrap";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import "bootstrap/dist/css/bootstrap.css";
import "./styles.css";
import uuid from "uuid";

function App() {
  const [items, setitems] = React.useState([
    { id: uuid(), name: "Dairy Free" },
    { id: uuid(), name: "Party Food" },
    { id: uuid(), name: "Family Sized" },
    { id: uuid(), name: "Low Cholesterol" },
    { id: uuid(), name: "Low Sodium" }
  ]);
  const removeitem = item => {
    setitems(items.filter(itemname => itemname.id !== item));
  };
  return (
    <div className="App">
      <TransitionGroup className="todo-list">
        {items.map(data => (
          <CSSTransition timeout={500} classNames="item" key={data.id}>
            <Button className="m-2" onClick={() => removeitem(data.id)}>
              {data.name}
            </Button>
          </CSSTransition>
        ))}
      </TransitionGroup>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

此问题已经解决here,因此请结帐以了解这种奇怪的行为。

答案 1 :(得分:0)

如果有人遇到此问题,以供将来参考。问题在于如何将key值传递给标签。

我的代码通过filter数组进行映射,并将每个值的index分配为子组件的键。这意味着它们的键号为0、1、2、3等。当从filter数组中删除标签并重新渲染页面时,将按照数组的顺序重新应用索引,这意味着他们全都转移了,而不是从原处“拔出”了被移除的那一个。

解决方案是使用一个完全不依赖数组索引值的唯一键。这是我更新的内容:

<TransitionGroup className='tag-container'>
  {filter.map((tag) => {
    return (
      <CSSTransition key={`active_${tag}`} timeout={250} classNames={`tag`}>
        <TagButton value={tag} onClick={onClickFunction} className={`${screenStyle} active`}>{tag}</TagButton>
      </CSSTransition>
    )
  })}
</TransitionGroup>