【问题标题】:How to animate the filtering of a list using useTransition in react-spring如何在 react-spring 中使用 useTransition 对列表的过滤进行动画处理
【发布时间】:2021-07-24 20:35:19
【问题描述】:

我正在尝试使用 react-spring v9.x 中的新 useTransition hook changes 过滤列表的过渡动画,以便在过滤列表项时,其余项目移动到新位置。

到目前为止,我已经设法让列表中的组件淡入和淡出,但是一旦淡出动画完成,其余组件就会立即跳转到它们的新位置。我无法改变这一点。

如何为其余组件设置动画以顺利移动到新位置?

这是当前代码的code sandbox link

在搜索栏输入“p”,可以看到跳跃效果最清晰,看到名称为Plum的组件在短暂延迟后跳起来。

App.js

import { useState } from "react";
import { useSpring, useTransition, animated } from "react-spring";

export default function App() {
  const [items, setItems] = useState([
    { name: "Apple", key: 1 },
    { name: "Banana", key: 2 },
    { name: "Orange", key: 3 },
    { name: "Kiwifruit", key: 4 },
    { name: "Plum", key: 5 }
  ]);

  const [searchText, setSearchText] = useState("");

  const filteredItems = items.filter((item) =>
    item.name.toLowerCase().includes(searchText.toLowerCase())
  );

  const transition = useTransition(filteredItems, {
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  });

  const fadeInListItems = transition((style, item) => {
    return (
      <animated.div style={style}>
        <Item data={item} />
      </animated.div>
    );
  });

  const handleSearchBarChange = ({ target }) => setSearchText(target.value);

  return (
    <div className="App">
      <h2>Click on an item to toggle the border colour.</h2>

      <SearchBar onChange={handleSearchBarChange} value={searchText} />

      {fadeInListItems}
    </div>
  );
}

const SearchBar = (props) => {
  return (
    <>
      <label>Search Bar: </label>
      <input onChange={props.onChange} value={props.searchText} type="text" />
    </>
  );
};

const Item = (props) => {
  const [isClicked, setIsClicked] = useState(false);

  const [styles, api] = useSpring(() => ({
    border: "2px solid black",
    margin: "5px",
    borderRadius: "25px",
    boxShadow: "2px 2px black",
    backgroundColor: "white",
    color: "black"
  }));

  const handleClick = (e) => {
    api.start({
      backgroundColor: isClicked ? "white" : "red",
      color: isClicked ? "black" : "white"
    });
    setIsClicked((prev) => !prev);
  };

  return (
    <animated.div style={styles} onClick={handleClick} key={props.data.key}>
      {props.data.name}
    </animated.div>
  );
};

【问题讨论】:

    标签: javascript reactjs react-spring


    【解决方案1】:

    您可以通过使用max-height(以及淡入淡出)隐藏过滤后的元素来实现该效果。这样,项目将“折叠”而不是仅仅消失,因此剩余的元素将“向上滑动”。

    转型

    const transition = useTransition(filteredItems, {
      from: { opacity: 0, marginTop: 5 },
      enter: { opacity: 1, maxHeight: 50, marginTop: 5 },
      leave: { opacity: 0, maxHeight: 0, marginTop: 0 }
    });
    

    我还加了overflow: hidden来完成maxHeight的效果,去掉了Itemmargin: 5px,因为我在transition--definition中加了margin。

    const [styles, api] = useSpring(() => ({
      border: "2px solid black",
    --  margin: "5px",
      borderRadius: "25px",
      boxShadow: "2px 2px black",
      backgroundColor: "white",
      color: "black",
    ++  overflow: "hidden",
    }));
    

    https://codesandbox.io/s/react-spring-demo-change-border-colour-on-click-forked-7fdkl

    【讨论】:

    • 这病了。我认为我可能会改变的一件事是错开不透明度变化和最大高度动画,例如:codesandbox.io/s/…
    • 手感不错!! :)
    • 这是一种比我接近它的方法更简单的方法。看起来棒极了!
    • @JoshuaWootonn It's Absolutely Beautiful
    • 谢谢!很高兴我能帮上忙
    猜你喜欢
    • 2020-08-23
    • 2015-12-01
    • 2019-05-06
    • 2019-11-27
    • 2021-07-10
    • 2019-10-29
    • 1970-01-01
    • 2021-08-03
    • 2021-07-12
    相关资源
    最近更新 更多