元素值在使用 react-transition-group 转换之前移动和更改
Element values shifting and changing before transition with react-transition-group
我在我正在处理的 gatsby 项目中使用 react-transition-group
包时注意到了这种行为。我有一个 "tags" 的列表,它们是从另一个主列表中挑选出来的,因此被添加到一个活动列表中。单击主列表中的标签将其添加到活动列表中,单击活动列表中的标签将其删除。与您期望的类似工作方式差不多。
转换 in 工作得很好,但是当转换 out 时,标签以一种奇怪的方式重新组织自己。我们有五个具有以下值的标签:
- 不含乳制品
- 派对食品
- 家庭大小
- 低胆固醇
- 低钠
如果您单击 Family Sized
标签将其删除,则会出现以下情况:
Family Sized
瞬间消失
Low Cholesterol
和Low 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
中有一个 <StaticQuery>
用于组件的相同 render()
方法(如果重要的话)。
<TagButton>
是来自 styled-components
包的样式组件,而不是单独导入的组件。
在你的数组中添加特定的标识符并在 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);
这个问题已经解决了,所以请检查以了解这个奇怪的行为。
以供日后有人遇到此问题时参考。问题在于如何将 key
值传递给标签。
我的代码通过 filter
数组进行映射,并将每个值的 index
分配为子组件的键。这意味着它们的键控为 0、1、2、3 等。当从 filter
数组和页面 re-renders 中删除标签时,索引为 re-applied,无论顺序如何数组在里面,这意味着它们都在移动,而不是被删除的那个从它原来的地方"plucked out"。
解决方案是使用一个完全不依赖于数组索引值的唯一键。这是我更新的内容:
<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>
我在我正在处理的 gatsby 项目中使用 react-transition-group
包时注意到了这种行为。我有一个 "tags" 的列表,它们是从另一个主列表中挑选出来的,因此被添加到一个活动列表中。单击主列表中的标签将其添加到活动列表中,单击活动列表中的标签将其删除。与您期望的类似工作方式差不多。
转换 in 工作得很好,但是当转换 out 时,标签以一种奇怪的方式重新组织自己。我们有五个具有以下值的标签:
- 不含乳制品
- 派对食品
- 家庭大小
- 低胆固醇
- 低钠
如果您单击 Family Sized
标签将其删除,则会出现以下情况:
Family Sized
瞬间消失Low Cholesterol
和Low 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
中有一个<StaticQuery>
用于组件的相同render()
方法(如果重要的话)。<TagButton>
是来自styled-components
包的样式组件,而不是单独导入的组件。
在你的数组中添加特定的标识符并在 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);
这个问题已经解决了
以供日后有人遇到此问题时参考。问题在于如何将 key
值传递给标签。
我的代码通过 filter
数组进行映射,并将每个值的 index
分配为子组件的键。这意味着它们的键控为 0、1、2、3 等。当从 filter
数组和页面 re-renders 中删除标签时,索引为 re-applied,无论顺序如何数组在里面,这意味着它们都在移动,而不是被删除的那个从它原来的地方"plucked out"。
解决方案是使用一个完全不依赖于数组索引值的唯一键。这是我更新的内容:
<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>