簡體   English   中英

如何在 react-spring 中使用 useTransition 對列表的過濾進行動畫處理

[英]How to animate the filtering of a list using useTransition in react-spring

我試圖在使用react-spring v9.x 中的新useTransition 鈎子更改過濾時為列表的過渡設置動畫,以便在過濾列表項時,剩余的項目移動到它們的新位置。

到目前為止,我已經設法讓列表中的組件淡入和淡出,但是一旦淡出 animation 完成,其余組件就會立即跳轉到它們的新位置。 我無法改變這一點。

如何為其余組件設置動畫以順利移動到新位置?

這是當前代碼的代碼沙箱鏈接

如果您在搜索欄中輸入“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>
  );
};

您可以通過使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM