Как анимировать тексты в событии onClick с помощью react-spring?

#javascript #reactjs #react-spring

#javascript #reactjs #react-spring

Вопрос:

Итак, я использую NextJS и React-spring для создания «Машины случайных цитат» (задача freecodecamp, которую я выполнил ранее, но я просто хотел попробовать что-то новое, например, используя nextjs и анимацию react-spring)

Итак, все работает хорошо, но когда я нажимаю на кнопку «Новая цитата», она генерирует новую цитату с анимацией затухания, чего не происходит, когда я нажимаю на кнопку. Это работает только при загрузке страницы в первый раз.

Есть ли какой-либо обходной путь для этого? Я также использовал chakraUI, но в нем нет различных анимаций или переходов. Моя ссылка на песочницу: 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 world"
          >
            Twitter
          </Button>
        </HStack>
      </Box>
    </Box>
  );
};

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

export default App;
 

Комментарии:

1. у вас есть ссылка на песочницу кода? (например, stackblitz)

2. @sivako codesandbox.io/s/compassionate-heisenberg-byulo? file=/pages/ … вот так.

Ответ №1:

Если вы сбрасываете spring конфигурацию, используя set метод для каждой новой цитаты, анимация должна работать.

Попробуйте эту разветвленную песочницу 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);
    }}
 

Комментарии:

1. Спасибо, это работает! Теперь мне просто нужно изменить цвет фона, чтобы сделать его еще круче.