倒计时没有更新,即使使用SetInterval。

huangapple go评论71阅读模式
英文:

Countdown is not updating even with SetInterval

问题

我正在尝试创建一个倒计时 Forge 应用,它接受一个日期类型的输入并根据实际日期开始倒计时。例如,我将输入设为“从现在开始的3天后”,但结果只显示为2天23小时59分钟59秒,并且结果不会每秒更新。

以下是主要函数:

const useCountdown = (targetDate) => {
  const countDownDate = new Date(targetDate).getTime();

  const [countDown, setCountDown] = useState(
    countDownDate - new Date().getTime()
  );

  useEffect(() => {
    const interval = setInterval(() => {
      setCountDown(countDownDate - new Date().getTime());
    }, 1000);

    return () => clearInterval(interval);
  }, [countDownDate]);

  return getReturnValues(countDown);
};

这是显示倒计时的地方:

const Edit = () => {
  const THREE_DAYS_IN_MS = 3 * 24 * 60 * 60 * 1000;
  const NOW_IN_MS = new Date().getTime();

  const dateTimeAfterThreeDays = NOW_IN_MS + THREE_DAYS_IN_MS;
  return (
    <>
      <Text>剩余时间 123</Text>
      <CountdownTimer targetDate={dateTimeAfterThreeDays} />
    </>
  );
};

export const renderFieldView = render(<View />);

我正在使用 Atlassian Forge 并将应用部署在 Jira 中。

英文:

I am trying to create a countdown forge application that takes an input of type date and starts counting based on the actual date.
As an example, I am giving as input "After 3 days from now", But I only get as a result, 2d:23h:59m:59s , ans this result is not updating every second.

Here is the main function:

const useCountdown = (targetDate) =&gt; {
const countDownDate = new Date(targetDate).getTime();

const [countDown, setCountDown] = useState(
countDownDate - new Date().getTime()
);

useEffect(() =&gt; {
const interval = setInterval(() =&gt; {
  setCountDown(countDownDate - new Date().getTime());
}, 1000);

return () =&gt; clearInterval(interval);
}, [countDownDate]);

return getReturnValues(countDown);
};

This is where I display the countdown:

const Edit = () =&gt; {

const THREE_DAYS_IN_MS = 3 * 24 * 60 * 60 * 1000;
const NOW_IN_MS = new Date().getTime();

const dateTimeAfterThreeDays = NOW_IN_MS + THREE_DAYS_IN_MS;
 return(
  &lt;Fragment&gt;
  &lt;Text&gt;Time left 123:&lt;/Text&gt;
  &lt;CountdownTimer targetDate={dateTimeAfterThreeDays} /&gt;
  &lt;/Fragment&gt;
   )
       };
    export const renderFieldView = render(&lt;View /&gt;);

I am using Atlassian forge and deploying the app in Jira.

答案1

得分: 1

我希望原帖作者现在已经找到了解决方案,但对于任何遇到这个帖子的人,我认为其中一部分原因导致它不起作用是因为它使用了 Atlassian 实现的 useEffect,它的工作方式与 React 不完全相同。

我在这篇博客中更详细地介绍了 Forge 如何在不同种类的应用中使用 hooks:https://blog.developer.atlassian.com/a-deeper-look-at-hooks-in-forge/

我可以确认,如果你使用 UI Kit 2(它使用 React hooks),那么它将会起作用。

英文:

I hope the original poster has found the solution by now, but for anyone coming across this post, I believe part of the reason this isn't working is because it's using UI Kit (original) which uses an Atlassian implementation of useEffect that doesn't work quite the same way as React.

I've written a bit more about how Forge uses hooks in each of the different kinds of apps in this blog https://blog.developer.atlassian.com/a-deeper-look-at-hooks-in-forge/

I can confirm, if you build this using UI Kit 2 (which uses React hooks) then it will work.

答案2

得分: 0

你确定你的控制台没有错误吗?

我唯一能想到的是使用毫秒 (Number) 作为 Date,或者反过来。

const { Fragment, useEffect, useState } = React;

const shiftDate = (date) =>
  new Date(date.getTime() - date.getTimezoneOffset() * 6e4);

const startOfYearLocal = (date) =>
  shiftDate(new Date(date.getFullYear(), 0, 1));

const dayOfYear = (date) =>
  Math.floor((date - startOfYearLocal(date)) / 864e5);

const getReturnValues = (dateInMillis) => {
  const date = new Date(dateInMillis);
  return {
    days: dayOfYear(date),
    hours: date.getHours(),
    minutes: date.getMinutes(),
    seconds: date.getSeconds(),
  };
};

const useCountdown = (targetDate) => {
  const countDownDate = new Date(targetDate).getTime();
  const [countDown, setCountDown] = useState(countDownDate - Date.now());
  useEffect(() => {
    const interval = setInterval(() =>
      setCountDown(countDownDate - Date.now()), 1000);
    return () => clearInterval(interval);
  }, [countDownDate]);
  return getReturnValues(countDown);
};

const Text = ({ children }) => <span>{children}</span>;

const CountdownTimer = ({ targetDate }) => {
  const { days, hours, minutes, seconds } = useCountdown(new Date(targetDate));
  return (
    <div className="CountdownTimer">
      <span>Days:</span><span>{days}</span>
      <span>Hours:</span><span>{hours}</span>
      <span>Minutes:</span><span>{minutes}</span>
      <span>Seconds:</span><span>{seconds}</span>
    </div>
  );
};

const Edit = () => {
  const THREE_DAYS_IN_MS = 2592e5;
  const NOW_IN_MS = Date.now();
  const dateTimeAfterThreeDays = NOW_IN_MS + THREE_DAYS_IN_MS;
  return (
    <Fragment>
      <Text>Time Left</Text>
      <CountdownTimer targetDate={dateTimeAfterThreeDays} />
    </Fragment>
  );
};

ReactDOM
  .createRoot(document.getElementById('root'))
  .render(<Edit />);
html, body, #root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

#root {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.CountdownTimer {
  display: grid;
  grid-template-columns: repeat(4, auto);
  grid-column-gap: 0.5rem;
  grid-row-gap: 0.25rem;
  padding: 1rem;
}

.CountdownTimer span {
  text-align: right;
}

.CountdownTimer span:nth-child(odd) {
  font-weight: bold;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
英文:

Are you sure you do not have an error in your console?

The only thing I can think of is using milliseconds (Number) as a Date or vice versa.

<!-- begin snippet: js hide: false console: true babel: true -->

<!-- language: lang-js -->

const { Fragment, useEffect, useState } = React;
const shiftDate = (date) =&gt;
new Date(date.getTime() - date.getTimezoneOffset() * 6e4);
const startOfYearLocal = (date) =&gt;
shiftDate(new Date(date.getFullYear(), 0, 1));
const dayOfYear = (date) =&gt;
Math.floor((date - startOfYearLocal(date)) / 864e5);
const getReturnValues = (dateInMillis) =&gt; {
const date = new Date(dateInMillis);
return {
days: dayOfYear(date),
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds(),
};
};
const useCountdown = (targetDate) =&gt; {
const countDownDate = new Date(targetDate).getTime();
const [countDown, setCountDown] = useState(countDownDate - Date.now());
useEffect(() =&gt; {
const interval = setInterval(() =&gt;
setCountDown(countDownDate - Date.now()), 1000);
return () =&gt; clearInterval(interval);
}, [countDownDate]);
return getReturnValues(countDown);
};
const Text = ({ children }) =&gt; &lt;span&gt;{children}&lt;/span&gt;;
const CountdownTimer = ({ targetDate }) =&gt; {
const { days, hours, minutes, seconds } = useCountdown(new Date(targetDate));
return (
&lt;div className=&quot;CountdownTimer&quot;&gt;
&lt;span&gt;Days:&lt;/span&gt;&lt;span&gt;{days}&lt;/span&gt;
&lt;span&gt;Hours:&lt;/span&gt;&lt;span&gt;{hours}&lt;/span&gt;
&lt;span&gt;Minutes:&lt;/span&gt;&lt;span&gt;{minutes}&lt;/span&gt;
&lt;span&gt;Seconds:&lt;/span&gt;&lt;span&gt;{seconds}&lt;/span&gt;
&lt;/div&gt;
);
};
const Edit = () =&gt; {
const THREE_DAYS_IN_MS = 2592e5;
const NOW_IN_MS = Date.now();
const dateTimeAfterThreeDays = NOW_IN_MS + THREE_DAYS_IN_MS;
return (
&lt;Fragment&gt;
&lt;Text&gt;Time Left&lt;/Text&gt;
&lt;CountdownTimer targetDate={dateTimeAfterThreeDays} /&gt;
&lt;/Fragment&gt;
);
};
ReactDOM
.createRoot(document.getElementById(&#39;root&#39;))
.render(&lt;Edit /&gt;);

<!-- language: lang-css -->

html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#root {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.CountdownTimer {
display: grid;
grid-template-columns: repeat(4, auto);
grid-column-gap: 0.5rem;
grid-row-gap: 0.25rem;
padding: 1rem;
}
.CountdownTimer span {
text-align: right;
}
.CountdownTimer span:nth-child(odd) {
font-weight: bold;
}

<!-- language: lang-html -->

&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月16日 03:01:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定