[copy airbnb] 9、预定组件(Listing reservation component)

1、differenceInDays

下面是如何使用 differenceInDays 的基本示例(假设您正在使用 date-fns ):

import { differenceInDays } from 'date-fns';

const start = new Date(2023, 3, 22); // April 22, 2023
const end = new Date(2023, 3, 25);   // April 25, 2023
const dayCount = differenceInDays(end, start);

console.log(dayCount); // Output: 3

在此示例中, differenceInDays 是从 date-fns 导入的,它用于查找 start 和 end 日期之间的天数。该函数接受两个参数:结束日期和开始日期,并以数字形式返回天数。

2、eachDayOfInterval

eachDayOfInterval 是 date-fns 这个日期操作库中的一个函数,它的主要功能是返回两个日期之间每一天的数组。该函数接收一个包含 start 和 end 属性的对象作为参数,分别对应时间间隔的开始日期和结束日期。下面是一个简单的示例,说明如何使用 eachDayOfInterval

import { eachDayOfInterval } from 'date-fns';

const start = new Date(2023, 3, 1); // 表示 2023 年 4 月 1 日
const end = new Date(2023, 3, 5); // 表示 2023 年 4 月 5 日

const interval = {
  start: start,
  end: end
};

const daysArray = eachDayOfInterval(interval);

console.log(daysArray);
// 输出: 
// [
//   2023-04-01T00:00:00.000Z,
//   2023-04-02T00:00:00.000Z,
//   2023-04-03T00:00:00.000Z,
//   2023-04-04T00:00:00.000Z,
//   2023-04-05T00:00:00.000Z
// ]

在这个例子中,eachDayOfInterval 函数返回了从 2023 年 4 月 1 日到 2023 年 4 月 5 日之间的每一天的日期对象组成的数组。

这个函数在需要处理一个时间范围内的每一天时非常有用,比如生成日历视图、计算时间段内的活动日数,或者其他需要逐日操作的情况。

3、react-date-range、@types/react-date-range

react-date-range 是一个用于 React 项目的日期选择组件库,它允许用户选择单个日期或日期范围。它与日期库无关,但使用 date-fns 来处理日期操作。react-date-range 提供了灵活的组件,如 DateRangePicker 和 Calendar,这些组件可以直接在你的应用中使用。

@types/react-date-range 是 react-date-range 的 TypeScript 类型定义。由于 react-date-range 本身不包含类型定义,因此,如果你使用 TypeScript 开发你的应用,你可能需要安装 @types/react-date-range 来提供类型定义,这样可以在使用该库时获得类型检查和智能提示。

  • 安装准备
    npm i @types/react-date-range
    npm i react-date-range
  • 样式准备

    在使用组件的地方引入样式:
    import “react-date-range/dist/styles.css”;
    import “react-date-range/dist/theme/default.css”

    在globals.css写入(为了让组件充满父容器):
    .rdrMonth{ width: 100%!important; }
    .rdrCalendarWrapper{ width: 100% !important; font-size: 16px!important; }

4、useCallback、useMemo使用场景

  • useCallback 是 React 中的一个钩子(Hook),它返回一个记忆版的回调函数。这个回调函数只有在它的依赖发生改变时才会更新。一般来讲,useCallback 在以下场景中特别有用:
    • 传递回调到经过优化的子组件
      当你将回调函数作为 props 传递给子组件,并且子组件进行了性能优化(例如使用 React.memo 或 shouldComponentUpdate)时,如果父组件重新渲染,未经过 useCallback 记忆的回调函数将被视为新的 props,从而引发子组件的不必要渲染。使用 useCallback 记忆的回调函数可以避免这种情况,只有当回调函数的依赖项改变时,子组件才会更新。
    • 防止依赖于回调的副作用不必要地重新执行
      在 useEffect 和其它依赖于回调函数的钩子中,如果回调没有使用 useCallback,那么在每次组件渲染时都会被认为是新的函数,导致 useEffect 中的副作用逻辑重新执行,这通常是你想要避免的,因为它可能会导致额外的性能开销。
    • 避免计算昂贵的计算
      如果回调函数内部包含了复杂的计算逻辑,使用 useCallback 可以确保函数体不会在每次渲染时重新创建和执行,从而省去重复执行昂贵计算的资源消耗。
    • 引用稳定性
      当回调函数被传递给需要稳定引用的自定义钩子、第三方库或者组件时,使用 useCallback 可以确保函数引用保持稳定。
    • 正是因为函数在 JavaScript 中是一等公民,并且它们在每次渲染时都会创建一个新的实例,useCallback 在各种需要优化和控制函数重新创建的场景中变得十分有用。然而,建议仅在确实需要时才使用 useCallback,因为过度优化可能会引入额外的复杂性,并且并不是所有的函数都需要记忆。如果函数体不大,且不依赖于组件外部的计算结果,那么对性能的优化也许是微不足道的。
  • useMemo
    是 React 提供的一个 Hook,它用于缓存复杂计算的结果,从而避免在每次组件渲染时进行重复的计算。通过记忆计算结果,useMemo 提高了应用的性能,特别是对于那些计算成本较高的操作来说。以下是 useMemo 的一些典型使用场景:
    • 优化昂贵的计算
      当组件中包含需要大量计算资源的逻辑时,可以使用 useMemo 来缓存这些计算的结果。这样,只有当依赖项发生变化,才会重新执行计算,否则直接使用缓存的值。这减少了不必要的计算成本,特别是在频繁渲染的场景中。
    • 避免子组件不必要的重新渲染
      类似于 useCallbackuseMemo 也可以用来确保传递给子组件的 prop 在引用不变的情况下保持稳定。如果计算得到的值作为 prop 传递给了一个经过 React.memo 优化的子组件,那么只有当这个值真正发生变化时,子组件才会重新渲染。
    • 缓存资源密集型的操作结果
      对于那些需要进行复杂的数据处理或转换(比如过滤和排序大型数据集)的场景,useMemo 可以用来缓存处理结果。这避免了在每次渲染时重复进行资源密集型操作,尤其在响应用户操作时保持界面的流畅性。
    • 引用相等性保持
      对于那些需要严格比较引用是否相等的场景(根据引用相等性来决定是否执行某些操作),useMemo 可以缓存一个对象或数组等引用类型的值。这样可以在依赖项未变时避免创建新的引用,从而避免引发额外的渲染或执行。
    • const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
      在这个示例中,computeExpensiveValue 是一个假设的昂贵计算函数,它依赖于 a 和 b 两个变量。通过使用 useMemo,该函数的结果被缓存,只有当 a 或 b 变化时,才会重新计算 expensiveValue
    • 简而言之,useMemo 在需要对昂贵的计算结果进行缓存、优化渲染性能、避免不必要的子组件渲染、以及保持引用相等性的场景中非常有用。然而,和 useCallback 一样,应当谨慎使用 useMemo,避免过度优化及增加代码复杂性。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部