如何使用 react-spring 在 onClick 事件上设置动画文本?

How to animate texts on onClick event using react-spring?

所以,我正在使用 NextJs 和 React-spring 制作“随机报价机”(我之前完成的 freecodecamp 挑战,但我只是想尝试新事物,例如使用 nextjs 和 React -spring动画)

所以一切正常,但是当我点击“新报价”按钮时,它会生成一个带有淡入动画的新报价,当我点击按钮时它不会。它只在第一次加载页面时有效。

有什么解决方法吗?我也使用过 chakraUI,但它没有各种动画或过渡。 我的沙盒 link:https://codesandbox.io/s/compassionate-heisenberg-byulo?file=/pages/index.js

下面是我到目前为止编写的代码:

import * as React from "react";
import { useState, useCallback } from "react";
import {
  ChakraProvider,
  Box,
  Text,
  Button,
  Icon,
  Flex,
  HStack,
  Heading,
  Link
} from "@chakra-ui/react";
import { FaTwitter, FaQuoteLeft } from "react-icons/fa";
import quoteArray from "../pages/day/quotes";
import { useSpring, animated } from "react-spring";

const Title = () => {
  return (
    <Box>
      <Heading mt="1%" align="center">
        Random Quote Generator
      </Heading>
    </Box>
  );
};

const QuoteBox = () => {
  const [loading, setLoading] = useState(true);
  const [quote, setQuote] = useState(null);
  const props = useSpring({
    from: { opacity: 0 },
    to: { opacity: 1 }
  });

  const onQuoteChange = useCallback(() => {
    setLoading(true);
    const randomQuote =
      quoteArray[Math.floor(Math.random() * quoteArray.length)];
    setLoading(false);
    setQuote(randomQuote);
  }, []);

  React.useEffect(() => {
    onQuoteChange();
  }, [onQuoteChange]);

  return (
    <Box>
      <Title />
      <Box
        width="50%"
        height="100%"
        border="1px"
        boxShadow="md"
        p={5}
        rounded="md"
        bg="white"
        borderColor="gray.400"
        mx="auto"
        my="10%"
      >
        <Box>
          <Flex>
            <Box>
              <Icon as={FaQuoteLeft} w={7} h={6} />
              <animated.div style={props}>
                <Text fontSize="2xl">
                  {loading || !quote ? "..." : quote.quote}
                </Text>
              </animated.div>
            </Box>
          </Flex>
        </Box>
        <Box>
          <animated.div style={props}>
            <Text fontSize="xl" align="right">
              -{loading || !quote ? "..." : quote.author}
            </Text>
          </animated.div>
        </Box>

        <HStack mt="2%" ml="1%" spacing="2%">
          <Button colorScheme="blue" size="sm" onClick={onQuoteChange}>
            New Quote
          </Button>

          <Button
            as={Link}
            colorScheme="twitter"
            size="sm"
            leftIcon={<FaTwitter />}
            target="_blank"
            href="https://twitter.com/intent/tweet?text=Hello%20world"
          >
            Twitter
          </Button>
        </HStack>
      </Box>
    </Box>
  );
};

function App() {
  return (
    <ChakraProvider>
      <QuoteBox />
    </ChakraProvider>
  );
}

export default App;

如果您在每个新报价上使用 set 方法重置 spring 配置,动画应该可以正常工作。

试试这个分叉的沙箱 https://codesandbox.io/s/competent-rgb-umgx5?file=/pages/index.js

改变 1

const states = [
  {
    config: { duration: 1250 },
    from: { opacity: 0.2, color: "green" },
    to: { opacity: 0.6, color: "red" }
  },
  {
    config: { duration: 1250 },
    from: { opacity: 0.2, color: "red" },
    to: { opacity: 0.6, color: "green" }
  }
];

更改 2(更改 useSpring 的用法)

  const [toggle, setToggle] = useState(false);
  const [props, set] = useSpring(() => ({
    ...states[+toggle]
  }));

更改 3(更新 newQuote 回调以调用 set

    onClick={() => {
      onQuoteChange();
      set({
        ...states[+!toggle]
      });
      setToggle(!toggle);
    }}