#javascript #reactjs
#javascript #reactjs
Вопрос:
В настоящее время я могу получать данные дни текущего месяца, а также предыдущие и будущие месяцы с помощью JS. Чего я хотел бы добиться, так это того, что, скажем, декабрь начинается во вторник, я хотел бы передать пустые объекты для воскресенья и понедельника. Декабрь также заканчивается в четверг, поэтому я хотел бы передать пустые объекты для пятницы и субботы.
Код, который я в настоящее время использую для извлечения каждого календарного месяца и их отображения, выглядит следующим образом:
import React, { useEffect, useState, useCallback } from "react";
import "./styles.css";
export default function App() {
const [visibleMonth, setVisibleMonth] = useState(new Date().getMonth());
const [calData, setCalData] = useState(null);
const [dates, setDates] = useState(null);
const getDaysArray = async (s, e) => {
let a = [];
for (let d = new Date(s); d <= e; d.setDate(d.getDate() 1)) {
a.push(new Date(d).toString());
}
return a;
};
const currentMonth = useCallback(async () => {
let d = new Date();
d.setMonth(visibleMonth);
let firstDay = new Date(d.getFullYear(), d.getMonth(), 1);
let lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() 1, 0);
let calendarMonth = d.toLocaleString("en-us", {
month: "long",
year: "numeric"
});
setCalData(calendarMonth);
const dates = await getDaysArray(firstDay, lastDay);
setDates(dates);
}, [visibleMonth]);
useEffect(() => {
currentMonth();
}, [currentMonth]);
const prevMonth = async () => {
let d = new Date();
d.setMonth(visibleMonth - 1);
setVisibleMonth((state) => visibleMonth - 1);
let firstDay = new Date(d.getFullYear(), d.getMonth(), 1);
let lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() 1, 0);
let calendarMonth = d.toLocaleString("en-us", {
month: "long",
year: "numeric"
});
setCalData(calendarMonth);
const dates = await getDaysArray(firstDay, lastDay);
setDates(dates);
};
const nextMonth = async () => {
let d = new Date();
d.setMonth(visibleMonth 1);
setVisibleMonth((state) => visibleMonth 1);
let firstDay = new Date(d.getFullYear(), d.getMonth(), 1);
let lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() 1, 0);
let calendarMonth = d.toLocaleString("en-us", {
month: "long",
year: "numeric"
});
setCalData(calendarMonth);
const dates = await getDaysArray(firstDay, lastDay);
setDates(dates);
};
return (
<div className="App">
<h1>{calData}</h1>
<button onClick={prevMonth}>Prev Month</button>
<button onClick={nextMonth}>Next Month</button>
{dates amp;amp;
dates.map((item, i) => {
return <div key={i}>{item}</div>;
})}
</div>
);
}
причина, по которой я пытаюсь это сделать, связана с созданной мной сеткой. В нынешнем виде каждый месяц начинается в воскресенье, и я не могу успешно сопоставить правильные дни месяца с днями в календаре. Например, декабрь начинается во вторник, но мой стиль показывает, что он начинается в воскресенье. любая помощь будет с благодарностью. в журналах консоли в настоящее время отображаются дни, в которые должен начинаться и заканчиваться каждый месяц.
Прилагается ручка с кодом для отладки! https://codesandbox.io/s/heuristic-visvesvaraya-r9lcw?file=/src/App.js
Комментарии:
1. Еще раз здравствуйте, Роберт — возможно, вы немного задумались об этом. У вас уже есть то, что вам нужно, предполагая, что вы собираетесь разместить это в сетке. Предполагая, что первый элемент сетки в строке, скажем, сетка 0, является воскресеньем, тогда использование
.getDay()
вернет размещение сетки для каждого дня. Это будет работать, потому.getDay()
что возвращает нулевое индексированное значение для каждого дня с — как вы уже догадались; Воскресенье равно 0. Итак, вторник, 1 декабря, будет автоматически и динамически отображаться в третьем элементе сетки (или сетке 2), потому.getDay()
что вернет 2. Надеюсь, это поможет.2. так я бы вызвал getDay() в цикле for?
3. Трудно отвечать на общие вопросы, не понимая вашего дизайна. Например, я понятия не имею, почему вы храните даты в виде строк, зная, что вы хотите делать что-то, основываясь на том, что они являются точными датами (а не строками). Поэтому я не могу ответить на этот вопрос.
4. Я внес изменения в свой вопрос и песочницу, чтобы показать мой текущий стиль и почему я пытаюсь заполнить пустые дни
Ответ №1:
Основываясь на ваших последних комментариях и обновлениях, я рекомендую внести следующие изменения в getDaysArray()
метод:
- Создайте
d
дату вне цикла, чтобы использоватьgetDay()
(день недели #) a[]
Заполните пустыми строками с номером дня недели # в цикле for- Наконец, заполните строки даты в оставшуюся часть
a[]
массива.
Это должно сделать это:
const getDaysArray = async (s, e) => {
let a = [];
let d = new Date(s);
let emptyCount = d.getDay();
for(let i = 0; i < emptyCount; i ) {
a.push('');
}
for (d; d <= e; d.setDate(d.getDate() 1)) {
a.push(new Date(d).toString());
}
return a;
};
Комментарии:
1. вы, сэр, джентльмен и ученый, вы упоминали ранее, что я не должен хранить даты в виде строки, должен ли я преобразовать их в строку после сопоставления?
2. Теперь, когда я увидел ваши намерения с ними, они в порядке. Я на самом деле выступаю за форматирование даты с использованием строк — до последних версий API Date это был самый простой / быстрый способ выполнить это (форматирование даты). Как вы делаете. Это выглядит хорошо.
3. спасибо, Рэнди, ты мне очень помог! и я также ценю ваше объяснение вашей логики
4. Добро пожаловать. До следующего раза 🙂