ReactJS应用如何计算两个日期间周日数量并在提交后展示
问题描述
开发ReactJS应用时,需要实现点击提交按钮后,展示所选起止日期之间的周日总数。目前已经完成开始日期、结束日期输入控件、提交按钮的表单布局,但存在两个问题:
- 现有代码存在重复嵌套
Calculate组件定义的语法错误 - 不清楚
submitHandler中的周日计数计算逻辑、结果展示的实现方式
原始存在错误的代码如下:
import React from 'react' import {useState} from 'react' const Calculate = () => { const [inputDate,setInputDate] = useState({ sdate:'', edate:'', }); const onChangeHandler = (e)=>{ let name =e.target.name let value = e.target.value const Calculate = () => { const [inputDate,setInputDate] = useState({ sdate:'', edate:'', }); const onChangeHandler = (e)=>{ let name =e.target.name let value = e.target.value setInputDate({...inputDate,[name]:value}) } const submitHandler=(e)=>{ e.preventDefault(); } return ( <div> <form action=""> <div> <div> <label htmlFor="">Start Date</label> <input type="date" name="sdate" onChange={onChangeHandler}/> </div> <div> <label htmlFor="">End Date</label> <input type="date" name="edate" onChange={onChangeHandler}/> </div> <button>Submit</button> </div> </form> </div> ) } export default Calculate <!-- end snippet --> setInputDate({...inputDate,[name]:value}) } const submitHandler=(e)=>{ e.preventDefault(); } return ( <div> <form action=""> <div> <div> <label htmlFor="">Start Date</label> <input type="date" name="sdate" onChange={onChangeHandler}/> </div> <div> <label htmlFor="">End Date</label> <input type="date" name="edate" onChange={onChangeHandler}/> </div> <button>Submit</button> </div> </form> </div> ) } export default Calculate
实现方案
首先清理代码里冗余的嵌套组件定义,再按以下步骤实现功能:
- 新增独立state存储周日计数结果,初始值设为
null,用于区分未提交和提交后结果为0的场景 - 核心计数逻辑说明:JS原生
Date对象的getDay()方法返回0-6对应周日到周六,返回值为0时即为周日;遍历从开始日期到结束日期的每一天,统计符合条件的日期总数即可 - 在
submitHandler中完成日期格式转换、合法性校验、计数计算,将结果存入对应的state - 在表单下方新增结果展示区块,当计数结果不为
null时渲染最终统计值 - 给表单绑定
onSubmit事件触发submitHandler,给按钮添加type="submit"属性
修复后完整代码
import React, { useState } from 'react' const Calculate = () => { const [inputDate, setInputDate] = useState({ sdate: '', edate: '', }); // 存储周日计数结果 const [sundayCount, setSundayCount] = useState(null); const onChangeHandler = (e) => { const name = e.target.name const value = e.target.value setInputDate({ ...inputDate, [name]: value }) } const submitHandler = (e) => { e.preventDefault(); const { sdate, edate } = inputDate; // 校验日期是否完整选择 if (!sdate || !edate) { alert('请选择完整的起止日期'); return; } const start = new Date(sdate); const end = new Date(edate); // 校验日期顺序合法性 if (end < start) { alert('结束日期不能早于开始日期'); return; } let count = 0; const currentDate = new Date(start); // 遍历区间内所有日期 while (currentDate <= end) { // getDay()返回0即为周日 if (currentDate.getDay() === 0) { count++; } // 日期向后推1天 currentDate.setDate(currentDate.getDate() + 1); } setSundayCount(count); } return ( <div> <form onSubmit={submitHandler}> <div> <div> <label>Start Date</label> <input type="date" name="sdate" onChange={onChangeHandler} /> </div> <div> <label>End Date</label> <input type="date" name="edate" onChange={onChangeHandler} /> </div> <button type="submit">Submit</button> </div> </form> {/* 结果展示区域 */} {sundayCount !== null && ( <div style={{ marginTop: '16px' }}> *所选日期区间内的周日总数为:{sundayCount}* </div> )} </div> ) } export default Calculate
注意:上述计数逻辑默认包含起止日期本身,如果起止日期刚好是周日也会被计入总数,如果需要排除边界日期可以自行调整循环的起止判断条件。
内容的提问来源于stack exchange,提问作者Venkat
相关产品推荐
相关产品推荐

