内部无状态类的反应功能组件

发布于 2025-02-01 04:37:20 字数 4833 浏览 5 评论 0原文

我想问或收集有关这种情况的一些重要建议。

我不是要创建自己的dateTimePicker react组件。我正在搜索一些代码以轻松构建日历。现在,我找到了一些常规类,这些类使日历制作,我想重新使用它来创建我的dateTimePicker组件。

现在,我想要求/打开建议,以获取更好或良好的练习,这对于我的组件是合乎逻辑的。

在下面的代码中,我有一个功能组件,其中包含一个无状态类day,我试图实例化以备将来使用。对我来说,它可以正常工作。由于我不想看我的代码非常凌乱或少行,因此是否可以将此day无状态类分开以将其导入我的功能组件中?还是对此有什么建议?还是任何人都可以向我解释我在做什么在逻辑上是错误的,因为我正在使用基于功能的组件并将其放入其中。我想听听一些很好的建议,以更好地实施。

import React, {useState} from "react";
import styles from "./Datetimepicker.module.scss";
import classNames from "classnames";
import CalendarSVG from "../../../styles/icons/Calendar/Calendar"

const Datetimepicker = (props) => {
  const {
    style,
    name,    
    color,
    size,    
    inputRef,
    errorMsg,
    helperMsg,
    placeholder,
    disabled,
    ...others
  } = props;

  
  const [addVisibility, setAddVisibility] = useState(false);

  const showCalendar = () => {
    setAddVisibility((prevState) => (!prevState));
  }

  const getWeekNumber = (date) => {
    const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
    const pastDaysOfYear = (date - firstDayOfTheYear) / 86400000;
    
    return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
  }

  class Day {
    constructor(date = null, lang = 'default') {
      date = date ?? new Date();    
      this.Date = date;
      this.date = date.getDate();
      this.day = date.toLocaleString(lang, { weekday: 'long'});
      this.dayNumber = date.getDay() + 1;
      this.dayShort = date.toLocaleString(lang, { weekday: 'short'});
      this.year = date.getFullYear();
      this.yearShort = date.toLocaleString(lang, { year: '2-digit'});
      this.month = date.toLocaleString(lang, { month: 'long'});
      this.monthShort = date.toLocaleString(lang, { month: 'short'});
      this.monthNumber = date.getMonth() + 1;
      this.timestamp = date.getTime();
      this.week = getWeekNumber(date);
    }
    
    get isToday() {
      return this.isEqualTo(new Date());
    }
    
    isEqualTo(date) {
      date = date instanceof Day ? date.Date : date;
      
      return date.getDate() === this.date &&
        date.getMonth() === this.monthNumber - 1 &&
        date.getFullYear() === this.year;
    }
    
    format(formatStr) {
      return formatStr
        .replace(/\bYYYY\b/, this.year)
        .replace(/\bYYY\b/, this.yearShort)
        .replace(/\bWW\b/, this.week.toString().padStart(2, '0'))
        .replace(/\bW\b/, this.week)
        .replace(/\bDDDD\b/, this.day)
        .replace(/\bDDD\b/, this.dayShort)
        .replace(/\bDD\b/, this.date.toString().padStart(2, '0'))
        .replace(/\bD\b/, this.date)
        .replace(/\bMMMM\b/, this.month)
        .replace(/\bMMM\b/, this.monthShort)
        .replace(/\bMM\b/, this.monthNumber.toString().padStart(2, '0'))
        .replace(/\bM\b/, this.monthNumber)
    }
  }

  const day = new Day();

  console.log('--day', day);

  return (
    <div className={styles.DatetimepickerWrapper}>
      <input
        className={classNames(
          styles.InputText,                
          errorMsg && styles.InputError,
          style ?? ""
        )}
        type="text"
        name={name}        
        placeholder={placeholder ?? "mm/dd/yyyy"}
        {...inputRef}
        {...others}
        disabled={disabled}        
      />
      <div className={addVisibility ? `${styles.CalendarVisible} ${styles.CalendarDropDown}` : `${styles.CalendarHidden}`}>
        <div className={styles.CalendarContainer}>
          <div className={styles.CalendarHeaderYear}>            
              <p>2022</p>            
          </div>
          <div className={styles.CalendarHeaderMonth}>
          <button type="button" className="prev-month" aria-label="previous month"></button>
            <h4 tabIndex="0" aria-label="current month">
              January
            </h4>
            <button type="button" className="prev-month" aria-label="next month"></button>
          </div>
          <div className={styles.CalendarDaysContainer}>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
          </div>          
        </div>        
      </div>
      <CalendarSVG width={23} fill="#294197" className={styles.CalendarDateTimePickerIcon} onClick={() => showCalendar()}/>  
      {errorMsg && <span className={styles.ErrorMessage}>{errorMsg}</span>}
      {!errorMsg && helperMsg && (
        <span className={styles.HelperMessage}>{helperMsg}</span>
      )}
    </div>
  );
};

export default Datetimepicker;

I would like to ask or gather some important suggestions for this situation.

I wan't to create my own Datetimepicker react component. I was searching some codes for easily constructing a calendar. Now I found some Regular Class which makes the calendar and I want to re-use it for creating my Datetimepicker component.

Now I would like to ask/open for suggestion for better or good practice that would be logical for my component.

In the code below, I have a functional component with a stateless class Day inside of it and I tried to instantiate it for future use. For me it works fine. Since I don't want to look my code very messy or make it fewer lines, Is there anyway to separate this Day stateless class to import it in my Functional component? or any suggestions for this?. Or Can anyone explain to me if what am I doing is logically wrong or not, since I was using a Functional based component and putting a class inside of it. I would like to hear some good advice for this to implement in much better way.

import React, {useState} from "react";
import styles from "./Datetimepicker.module.scss";
import classNames from "classnames";
import CalendarSVG from "../../../styles/icons/Calendar/Calendar"

const Datetimepicker = (props) => {
  const {
    style,
    name,    
    color,
    size,    
    inputRef,
    errorMsg,
    helperMsg,
    placeholder,
    disabled,
    ...others
  } = props;

  
  const [addVisibility, setAddVisibility] = useState(false);

  const showCalendar = () => {
    setAddVisibility((prevState) => (!prevState));
  }

  const getWeekNumber = (date) => {
    const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
    const pastDaysOfYear = (date - firstDayOfTheYear) / 86400000;
    
    return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
  }

  class Day {
    constructor(date = null, lang = 'default') {
      date = date ?? new Date();    
      this.Date = date;
      this.date = date.getDate();
      this.day = date.toLocaleString(lang, { weekday: 'long'});
      this.dayNumber = date.getDay() + 1;
      this.dayShort = date.toLocaleString(lang, { weekday: 'short'});
      this.year = date.getFullYear();
      this.yearShort = date.toLocaleString(lang, { year: '2-digit'});
      this.month = date.toLocaleString(lang, { month: 'long'});
      this.monthShort = date.toLocaleString(lang, { month: 'short'});
      this.monthNumber = date.getMonth() + 1;
      this.timestamp = date.getTime();
      this.week = getWeekNumber(date);
    }
    
    get isToday() {
      return this.isEqualTo(new Date());
    }
    
    isEqualTo(date) {
      date = date instanceof Day ? date.Date : date;
      
      return date.getDate() === this.date &&
        date.getMonth() === this.monthNumber - 1 &&
        date.getFullYear() === this.year;
    }
    
    format(formatStr) {
      return formatStr
        .replace(/\bYYYY\b/, this.year)
        .replace(/\bYYY\b/, this.yearShort)
        .replace(/\bWW\b/, this.week.toString().padStart(2, '0'))
        .replace(/\bW\b/, this.week)
        .replace(/\bDDDD\b/, this.day)
        .replace(/\bDDD\b/, this.dayShort)
        .replace(/\bDD\b/, this.date.toString().padStart(2, '0'))
        .replace(/\bD\b/, this.date)
        .replace(/\bMMMM\b/, this.month)
        .replace(/\bMMM\b/, this.monthShort)
        .replace(/\bMM\b/, this.monthNumber.toString().padStart(2, '0'))
        .replace(/\bM\b/, this.monthNumber)
    }
  }

  const day = new Day();

  console.log('--day', day);

  return (
    <div className={styles.DatetimepickerWrapper}>
      <input
        className={classNames(
          styles.InputText,                
          errorMsg && styles.InputError,
          style ?? ""
        )}
        type="text"
        name={name}        
        placeholder={placeholder ?? "mm/dd/yyyy"}
        {...inputRef}
        {...others}
        disabled={disabled}        
      />
      <div className={addVisibility ? `${styles.CalendarVisible} ${styles.CalendarDropDown}` : `${styles.CalendarHidden}`}>
        <div className={styles.CalendarContainer}>
          <div className={styles.CalendarHeaderYear}>            
              <p>2022</p>            
          </div>
          <div className={styles.CalendarHeaderMonth}>
          <button type="button" className="prev-month" aria-label="previous month"></button>
            <h4 tabIndex="0" aria-label="current month">
              January
            </h4>
            <button type="button" className="prev-month" aria-label="next month"></button>
          </div>
          <div className={styles.CalendarDaysContainer}>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
            <p>Test</p>
          </div>          
        </div>        
      </div>
      <CalendarSVG width={23} fill="#294197" className={styles.CalendarDateTimePickerIcon} onClick={() => showCalendar()}/>  
      {errorMsg && <span className={styles.ErrorMessage}>{errorMsg}</span>}
      {!errorMsg && helperMsg && (
        <span className={styles.HelperMessage}>{helperMsg}</span>
      )}
    </div>
  );
};

export default Datetimepicker;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清风不识月 2025-02-08 04:37:20

在可能的情况下,不应动态创建一个类。您将获得许多与他们自己的课程相关的单独实例,尽管有相同的名字,但实际上与众不同。

在这里,功能组件的外部范围中唯一的标识符日使用是getWeeKnumber,在构造函数中称为。但是getweeknumber也不会引用特定渲染的任何特定内容,因此它也可以移出 - 要么可以转移到其自己的独立函数,要么是一天的内部函数。您可以做到

class Day {
    constructor(date = null, lang = 'default') {
        date = date ?? new Date();
        this.Date = date;
        this.date = date.getDate();
        this.day = date.toLocaleString(lang, { weekday: 'long' });
        this.dayNumber = date.getDay() + 1;
        this.dayShort = date.toLocaleString(lang, { weekday: 'short' });
        this.year = date.getFullYear();
        this.yearShort = date.toLocaleString(lang, { year: '2-digit' });
        this.month = date.toLocaleString(lang, { month: 'long' });
        this.monthShort = date.toLocaleString(lang, { month: 'short' });
        this.monthNumber = date.getMonth() + 1;
        this.timestamp = date.getTime();
        this.week = this.getWeekNumber(date); // change this line
    }
    getWeekNumber(date) { // add this method
        const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
        const pastDaysOfYear = (date - firstDayOfTheYear) / 86400000;
        return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
    }
    // all the other code in Day is the same

,然后从功能组件中删除Day和getWeeKnumber

A class should not be dynamically created when possible. You'll get lots of individual instances tied to their own classes which are actually different despite having the same name.

Here, the only identifier Day uses from the outer scope of the functional component is the getWeekNumber, which is called in the constructor. But getWeekNumber doesn't reference anything particular to a particular render either, so it can be moved out too - either to its own standalone function, or to the inside of Day. You can do

class Day {
    constructor(date = null, lang = 'default') {
        date = date ?? new Date();
        this.Date = date;
        this.date = date.getDate();
        this.day = date.toLocaleString(lang, { weekday: 'long' });
        this.dayNumber = date.getDay() + 1;
        this.dayShort = date.toLocaleString(lang, { weekday: 'short' });
        this.year = date.getFullYear();
        this.yearShort = date.toLocaleString(lang, { year: '2-digit' });
        this.month = date.toLocaleString(lang, { month: 'long' });
        this.monthShort = date.toLocaleString(lang, { month: 'short' });
        this.monthNumber = date.getMonth() + 1;
        this.timestamp = date.getTime();
        this.week = this.getWeekNumber(date); // change this line
    }
    getWeekNumber(date) { // add this method
        const firstDayOfTheYear = new Date(date.getFullYear(), 0, 1);
        const pastDaysOfYear = (date - firstDayOfTheYear) / 86400000;
        return Math.ceil((pastDaysOfYear + firstDayOfTheYear.getDay() + 1) / 7)
    }
    // all the other code in Day is the same

and then remove Day and getWeekNumber from the functional component.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文