![](/img/trans.png)
[英]Simple animation with useTransition in react-spring
[英]Passing Functional Components to React Spring's useTransition
我正在尝试编写一个包含按钮面板的 React 组件,并且每个按钮都需要能够根据应用程序的 state 独立地打开和关闭。 为此,我创建了一个useTransition
,包裹在一个自定义挂钩中,它应该在收到新的 SVG 功能组件时触发转换。
我遇到的问题是,虽然按钮当前正在正确过渡,但我似乎无法让useTransition
在收到新组件时将它们换出。 当组件被替换为空数组时,它将删除一个,这是预期的,并且当传入一个新组件时,钩子内的useEffect
会触发,但由于某种原因, useTransition
不会接收到更改。
我猜它与组件之间的 object 相等性有关,但我不知道如何解决它而不用window.requestAnimationFrame
强制更改以设置 Z9ED39E2EA931586B6A985A6942EF7 两次。 这是一个带有最小演示的代码框。
父组件:
import React, { useState } from "react";
import { a } from "react-spring";
import "./styles.css";
import PlaySVG from "./svgs/PlaySVG";
import SaveSVG from "./svgs/SaveSVG";
import SearchSVG from "./svgs/SearchSVG";
import TrashSVG from "./svgs/TrashSVG";
import { useVertTransition } from "./Hooks";
export default function ActionButtons() {
const svgs = {
play: <PlaySVG style={{ width: "100%", height: "auto" }} id="play" />,
search: <SearchSVG style={{ width: "80%", height: "auto" }} id="search" />,
save: <SaveSVG style={{ width: "80%", height: "auto" }} id="save" />,
trash: <TrashSVG style={{ width: "80%", height: "auto" }} id="trash" />
};
const [actions, setActions] = useState({
one: svgs.play,
two: svgs.search,
three: svgs.trash
});
const [slotOne] = useVertTransition(actions.one);
const [slotTwo] = useVertTransition(actions.two);
const [slotThree] = useVertTransition(actions.three);
function buttonHandler() {
setActions({
...actions,
one: [],
two: svgs.save
});
}
return (
<div className="container">
<div className="panel">
<div className="button-container">
{slotOne.map(({ item, props, key }) => (
<a.button key={key} style={props} onClick={buttonHandler}>
{item}
</a.button>
))}
</div>
<div className="button-container">
{slotTwo.map(({ item, props, key }) => (
<a.button key={key} style={props} onClick={buttonHandler}>
{item}
</a.button>
))}
</div>
<div className="button-container">
{slotThree.map(({ item, props, key }) => (
<a.button key={key} style={props} onClick={buttonHandler}>
{item}
</a.button>
))}
</div>
</div>
</div>
);
}
useVertTransition 钩子:
import React, { useEffect } from "react";
import { useTransition } from "react-spring";
export function useVertTransition(item) {
useEffect(() => {
console.log(item);
}, [item]);
const vertTransition = useTransition(item, null, {
from: { transform: "translateY(-20px) rotateX(-90deg)", opacity: 0 },
enter: { transform: "translateY(0px) rotateX(0deg)", opacity: 1 },
leave: { transform: "translateY(20px) rotateX(90deg)", opacity: 0 },
trail: 400,
order: ["leave", "enter"]
});
return [vertTransition];
}
SVG 组件示例:
import React from "react";
function PlaySVG({ style }) {
return (
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24">
<path d="M7 6L7 18 17 12z" />
</svg>
);
}
export default PlaySVG;
你是对的,react-spring 无法检测到按钮之间的区别。 但它不检查项目,它只检查键。 所以你必须为唯一键添加一些东西。 因此,您可能希望将输入从 svg 更改为 object,在 svg 旁边包含一个名称。
const getSvg = name => ({ name, svg: svgs[name] });
const [actions, setActions] = useState({
one: getSvg("play"),
two: getSvg("search"),
three: getSvg("trash")
});
您现在可以添加密钥 function:
const vertTransition = useTransition(item, svg => svg.name, {
你应该改变渲染:
{slotOne.map(({ item, props, key }) => (
<a.button key={key} style={props} onClick={buttonHandler}>
{item.svg}
</a.button>
))}
现在它按预期工作。 我认为。
https://codesandbox.io/s/usetransition-demo-152zb?file=/src/ActionButtons.js:1253-1437
而且我还学到了一个新技巧,我从来没有使用过 order 属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.