Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

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

So, I am using NextJs and React-spring to make a "Random Quote Machine" (A freecodecamp challenge which I completed previously but I just wanted to try out new things,e.g using nextjs and react-spring animation)

So everything works well, but when I click on the "New Quote" button, it will generate a new quote with a fade-in animation, which it doesn't when I click on the button. It only works while loading the page for the first time.

Is there any workaround for this? I also used chakraUI but it doesn't have various animations or transitions. My sandbox link: https://codesandbox.io/s/compassionate-heisenberg-byulo?file=/pages/index.js

Below is the code I have written so far:

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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you reset the spring config using set method on each new quote, the animation should be working.

Try this forked sandbox https://codesandbox.io/s/competent-rgb-umgx5?file=/pages/index.js

Change 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" }
  }
];

Change 2 (change usage of useSpring)

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

Change 3 (update newQuote callback to call the set)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...