首页 > 解决方案 > 将 HTML 转换为 React 特定代码时遇到问题。我正在使用`@pqina/flip`?

问题描述

我正在使用https://github.com/pqina/flip并想Tick.count.down()使用 React 实现方法。示例中没有给出特定于 React 的代码,而且作者也被淹没了,所以我想在这里请教一些 React 专家。

我已经克隆了上面的 repo 并用以下代码替换了https://github.com/pqina/flip/tree/master/example/index.html内容。

我有以下 HTML 工作正常:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Count Down</title>

        <link rel="stylesheet" href="../dist/core/tick.core.min.css" />
    </head>
    <body>
        <style>
            .tick {
                font-size: 2rem;
            }
        </style>

        <p>Countdown from 10</p>
        <div class="tick" data-did-init="startNumericCountdown">
            <span data-view="text"></span>
        </div>

        <script>
            function startNumericCountdown(tick) {
                console.log(`start numeric countdown...`)
                var counter = Tick.count.down(10, 'seconds')
                counter.onupdate = function (value) {
                    tick.value = value
                }
                counter.onended = function () {
                    console.log(`countdown over `)
                }
            }
        </script>

        <script src="../dist/core/tick.core.kickstart.min.js"></script>
    </body>
</html>

当我尝试将其转换为 React 时,问题就来了。目前,我有以下代码:

import React, { useRef, useEffect } from "react";
import Tick from "@pqina/flip";
import "@pqina/flip/dist/flip.min.css";

export const FlipDate = ({ value }) => {
  const divRef = useRef();
  const tickRef = useRef();

  useEffect(() => {
    const didInit = tick => {
      console.log("didInit");

      console.log({ tick });
      tickRef.current = tick;
    };

    const currDiv = divRef.current;
    const tickValue = tickRef.current;
    Tick.DOM.create(currDiv, {
      value: Tick.count.down(10, 'seconds'),
      didInit
    });
    // divRef.current = Tick.count.down(10, 'seconds');

    return () => Tick.DOM.destroy(tickValue);
  });

  useEffect(() => {
    console.log({ tickRef });
    if (tickRef.current) {
      console.log({ divRef });
      tickRef.current.value = value;
    }
  }, [value]);

  return (
    <div ref={divRef} className="tick">
      <div data-repeat="true">
        <span data-view="flip">Tick</span>
      </div>
    </div>
  );
};

这不能按预期工作。flip正如您在我的演示中看到的那样,我的基本库正在工作: https ://codesandbox.io/s/react-flip-countdown-timer-8tin3?file=/src/App.js

其中 3 个文件是相同的代码:1 个使用类组件Flip.js,2 个使用 Hooks Flipr.js& Flippen.js

我想让FlipDate.js工作。它应该从 10 秒倒计时到 0 秒。上周一直在尝试这个,但无法解决这个问题。任何帮助表示赞赏

旁注:https ://github.com/pqina/flip使用https://github.com/pqina/tick underhood。

标签: javascriptreactjsref

解决方案


我也在 Reddit 的/r/reactjs上发布了同样的问题,并在那里找到了答案。这是一个有效的解决方案:

import React, { useRef, useEffect, useState } from "react";
import Tick from "@pqina/flip";
import "@pqina/flip/dist/flip.min.css";

export const WorkingFlipDate = ({ value }) => {
  const divRef = useRef();
  const tickRef = useRef();

  const [tickValue, setTickValue] = useState(value);

  // Make the Tick instance and store it in the refs
  useEffect(() => {
    const didInit = tick => {
      tickRef.current = tick;
    };

    const currDiv = divRef.current;
    const tickValue = tickRef.current;
    Tick.DOM.create(currDiv, {
      value,
      didInit
    });
    return () => Tick.DOM.destroy(tickValue);
  }, [value]);

  // Start the Tick.down process
  useEffect(() => {
    const counter = Tick.count.down(value, {
      format: ["d", "h", "m", "s"]
    });

    // When the counter updates, update React's state value
    counter.onupdate = function(value) {
      setTickValue(value);
    };

    // TODO: I don't know how to destroy this
    return () => {
      counter.onupdate = () => {};
    };
  }, [value]);

  // When the tickValue is updated, update the Tick.DOM element
  useEffect(() => {
    if (tickRef.current) {
      tickRef.current.value = tickValue;
    }
  }, [tickValue]);

  return (
    <div ref={divRef} className="tick">
      <div data-repeat="true">
        <span data-view="flip">Tick</span>
      </div>
    </div>
  );
};

推荐阅读