React Functional component with stateless class 内部
React Functional component with stateless class inside
我想针对这种情况询问或收集一些重要的建议。
我不想创建自己的 Datetimepicker React 组件。我正在搜索一些代码来轻松构建日历。现在我找到了一些制作日历的常规 Class,我想重新使用它来创建我的 Datetimepicker 组件。
现在我想 ask/open 征求对我的组件来说合乎逻辑的更好或良好做法的建议。
在下面的代码中,我有一个功能组件,里面有一个无状态 class Day
,我试图实例化它以备将来使用。对我来说效果很好。因为我不想让我的代码看起来很乱或者减少行数,所以有没有办法把这个 Day
stateless class 分开来导入我的 Functional 组件?或者对此有什么建议吗?或者任何人都可以向我解释我在做什么在逻辑上是否错误,因为我使用的是基于功能的组件并在其中放置了 class 。我想听听一些好的建议,以便以更好的方式实施。
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;
A class 不应尽可能动态创建。你会得到许多与它们自己的 classes 相关联的单独实例,尽管它们具有相同的名称,但它们实际上是不同的。
在这里,Day 在功能组件的外部范围内使用的唯一标识符是 getWeekNumber
,它在构造函数中调用。但是 getWeekNumber
也没有引用特定渲染的任何特定内容,因此它也可以移出 - 可以移到它自己的独立函数中,也可以移到 Day 的内部。你可以做到
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
。
我想针对这种情况询问或收集一些重要的建议。
我不想创建自己的 Datetimepicker React 组件。我正在搜索一些代码来轻松构建日历。现在我找到了一些制作日历的常规 Class,我想重新使用它来创建我的 Datetimepicker 组件。
现在我想 ask/open 征求对我的组件来说合乎逻辑的更好或良好做法的建议。
在下面的代码中,我有一个功能组件,里面有一个无状态 class Day
,我试图实例化它以备将来使用。对我来说效果很好。因为我不想让我的代码看起来很乱或者减少行数,所以有没有办法把这个 Day
stateless class 分开来导入我的 Functional 组件?或者对此有什么建议吗?或者任何人都可以向我解释我在做什么在逻辑上是否错误,因为我使用的是基于功能的组件并在其中放置了 class 。我想听听一些好的建议,以便以更好的方式实施。
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;
A class 不应尽可能动态创建。你会得到许多与它们自己的 classes 相关联的单独实例,尽管它们具有相同的名称,但它们实际上是不同的。
在这里,Day 在功能组件的外部范围内使用的唯一标识符是 getWeekNumber
,它在构造函数中调用。但是 getWeekNumber
也没有引用特定渲染的任何特定内容,因此它也可以移出 - 可以移到它自己的独立函数中,也可以移到 Day 的内部。你可以做到
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
。