首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >除非刷新页面,否则useEffect不会更新状态

除非刷新页面,否则useEffect不会更新状态
EN

Stack Overflow用户
提问于 2022-11-07 16:11:45
回答 1查看 49关注 0票数 0

我正在尝试创建一个计时器,它使用dayjs更新倒计时,并在某个截止时间(下午4点)之后更改交付日期,但是,除非刷新页面,否则useEffect似乎不会更新deliveryDate。计时器用完后,应自动更新交付日期。

`

代码语言:javascript
复制
import React, { useEffect, useState } from 'react'
import Countdown from 'react-countdown'
import dayjs from 'dayjs'

const FulfilmentDelivery = ({ cutoffhour }) => {
  const [cutoffTime, setCutoffTime] = useState(
    dayjs().add(1, 'day').hour(cutoffhour).minute(0).second(0)
  )
  const [deliveryDate, setDeliveryDate] = useState(
    dayjs().add(1, 'day').format('dddd D MMM')
  )

  let now = dayjs()
  let isSaturday = now.day() === 6
  let isSunday = now.day() === 0
  let cutoffFriday = now.day() === 5 && now.hour() >= cutoffhour

  useEffect(() => {
    // if it's after 4pm on a weekday set the cutoff time to the next day at 4pm and the delivery date to the next day
    if (now.hour() >= cutoffhour && !cutoffFriday && !isSaturday && !isSunday) {
      setCutoffTime(dayjs().add(1, 'day').hour(cutoffhour).minute(0).second(0))
      setDeliveryDate(dayjs().add(2, 'day').format('dddd D MMM'))
    }
    // if it's after 4pm on thursday, set delivery date and cutoff time to monday
    if (now.day() === 4 && now.hour() >= cutoffhour) {
      setCutoffTime(dayjs().add(4, 'day').hour(cutoffhour).minute(0).second(0))
      setDeliveryDate(dayjs().add(4, 'day').format('dddd D MMM'))
    }

    // if its before 4pm on a friday set delivery date and cutoff time to monday
    if (now.day() === 5 && now.hour() < cutoffhour) {
      setCutoffTime(dayjs().add(3, 'day').hour(cutoffhour).minute(0).second(0))
      setDeliveryDate(dayjs().add(3, 'day').format('dddd D MMM'))
    }

    // if it's the saturday set delivery date and cutoff time to tuesday
    if (isSaturday) {
      setCutoffTime(dayjs().add(3, 'day').hour(cutoffhour).minute(0).second(0))
      setDeliveryDate(dayjs().add(3, 'day').format('dddd D MMM'))
    }

    // if it's the saturday set delivery date and cutoff time to tuesday
    if (isSunday) {
      setCutoffTime(dayjs().add(2, 'day').hour(cutoffhour).minute(0).second(0))
      setDeliveryDate(dayjs().add(2, 'day').format('dddd D MMM'))
    }

    // if it's after 4pm on a friday set delivery date to tuesdsay
    if (cutoffFriday) {
      setDeliveryDate(dayjs().add(4, 'day').format('dddd D MMM'))
    }
  })

  return (
    <div className="align-items-center  d-flex  h-100">
      <span className="display-5" data-icon="z"></span>
      <div className="ps-2  w-100">
        {/* <span className="fw-bold fs-4">Order within</span> */}
        <Countdown
          date={cutoffTime}
          renderer={({ hours, minutes, seconds, completed }) =>
            (cutoffFriday && (
              <>
                <span className="fw-bold fs-6">Order now</span>{' '}
                <span>for delivery on {deliveryDate}</span>
              </>
            )) ||
            (isSaturday && (
              <>
                <span className="fw-bold fs-6">Order now</span>{' '}
                <span>for delivery on {deliveryDate}</span>
              </>
            )) ||
            (isSunday && (
              <>
                <span className="fw-bold fs-6">Order now</span>{' '}
                <span>for delivery on {deliveryDate}</span>
              </>
            )) || (
              <>
                <span className="fw-bold fs-6">Order within</span>{' '}
                <span className="text-danger fw-bold fs-6">
                  {`undefined` !== typeof window &&
                    `${hours >= 1 ? `${hours} hrs ` : ``}${
                      minutes >= 1 ? `${minutes} mins` : ``
                    }${seconds >= 1 ? ` ${seconds} sec` : ``}`}
                </span>
                <br /> for delivery on {deliveryDate}
              </>
            )
          }
        />
      </div>
    </div>
  )
}

export default FulfilmentDelivery

`

EN

回答 1

Stack Overflow用户

发布于 2022-11-07 18:12:32

您可以添加一个间隔来定期刷新状态。我想说这是你最好的选择,因为没有其他的反应。

它就像在其中使用setInterval调用来实现挂载效果一样简单。

代码语言:javascript
复制
const FulfilmentDelivery = ({ cutoffhour }) => {
  const now = dayjs();

  const [cutoffTime, setCutoffTime] = useState(
    now.add(1, "day").hour(cutoffhour).minute(0).second(0)
  );
  const [deliveryDate, setDeliveryDate] = useState(now.add(1, "day").format("dddd D MMM"));

  const choose = () => {
    const conditions = {
      // In order of precedence
      isSunday: now.day() === 0,
      // etc
    };

    applyDayAddConfig(conditions);
  };

  useEffect(() => {
    const ref = setInterval(() => choose(), 5000); // Refresh all of the state every 5 seconds
    return () => {
      clearInterval(ref);
    };
    // This is a mount effect because its dependency list is empty
  }, [choose]);

  // Might as well remove all the unnecessary duplication
  const applyDayAddConfig = (conds: object) => {
    const thisCond = Object.entries(conds).find(([_, value]) => value === true);
    const [timeDayAdd, dateDayAdd] = {
      isSunday: [2, 2],
      isSaturday: [3, 3],
      // Add config here
    }[thisCond[0]];

    setCutoffTime(now.add(timeDayAdd, "day").hour(cutoffhour).minute(0).second(0));
    if (dateDayAdd !== null) setDeliveryDate(now.add(dateDayAdd, "day").format("dddd D MMM"));
  };

  return;
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74349597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档