元素值在使用 react-transition-group 进行转换之前移动和更改

Posted

技术标签:

【中文标题】元素值在使用 react-transition-group 进行转换之前移动和更改【英文标题】:Element values shifting and changing before transition with react-transition-group 【发布时间】:2019-11-07 10:11:42 【问题描述】:

我在我正在处理的 gatsby 项目中使用 react-transition-group 包时注意到了这种行为。我有一个“标签”列表,这些“标签”是从另一个主列表中挑选出来的。单击主列表中的标签会将其添加到活动列表中,单击活动列表中的标签会将其删除。就像你期望的那样工作。

in 过渡效果很好,但是在过渡out 时,标签会以一种奇怪的方式重新组织自己。我们有五个具有以下值的标签:

不含乳制品 派对食品 家庭大小 低胆固醇 低钠

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

    Family Sized 瞬间消失 Low CholesterolLow Sodium 立即向左移动 最后一个标签立即变为Low Sodium 最后一个标签,现在的值是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 是一个从组件状态解构的数组。 如果重要的话,有一个来自gatsby&lt;StaticQuery&gt; 用于组件的相同render() 方法中。 &lt;TagButton&gt; 是来自styled-components 包的样式化组件,而不是单独导入的组件。

【问题讨论】:

【参考方案1】:

在您的数组中添加特定标识符并将每个元素的键设置为 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,所以请结帐了解这个奇怪的行为。

【讨论】:

谢谢,这解决了问题【参考方案2】:

如果有人遇到此问题,以供将来参考。问题在于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>

【讨论】:

以上是关于元素值在使用 react-transition-group 进行转换之前移动和更改的主要内容,如果未能解决你的问题,请参考以下文章

基于属性值在上下文节点上使用 sum()

name值与id值在Js获取元素时的区别

从顺序表中删除给定值在s到t之间(含s和t)的所有元素

线性表练习之Example024-从顺序表种删除值在 [s, t] 之间的所有元素

线性表练习之Example023-从有序顺序表种删除值在 (s, t) 之间的所有元素

从有序表L中删除值在给定值s到t之间(含s和t)的所有元素