React函数组件:如何在HTML渲染前修改useRef值?
问题:React函数组件中渲染前重置useRef变量值的需求
我在React函数组件中尝试在HTML渲染完成前修改useRef的值,曾尝试使用useEffect,但useEffect在HTML渲染后执行,无法满足需求。我的需求是在HTML渲染前将useRef变量multiDayPlaceHFactor的值重置为0,以便为下一周或上一周的事件更新该变量。
相关代码如下:
const Week = ({ events, weekDates, currentDate, toggle }: Props) => { const { startHour: START_HOUR, endHour: END_HOUR } = useStore(); const [multiDayEvents, setMultiDayEvents] = useState<any[]>([]); const [showAllMultiDEvents, setShowMultiDEvents] = useState<boolean>(false); // const [multiDPlaceHeight, setMultiDHeight] = useState<number>(0); const hours = eachMinuteOfInterval( { start: new Date(new Date().setHours(START_HOUR)).setMinutes(0), end: new Date(new Date().setHours(END_HOUR)).setMinutes(0), }, { step: 60 } ); const multiDayPlaceHFactor = useRef(0); const computeMultiDPHeight = (val: number) => { return val > 2 && !showAllMultiDEvents ? 3 * 28 : val * 28; }; // useEffect(() => { // multiDayPlaceHFactor.current = 0; // // eventsIndexes.current = []; // console.log('------------------------------------'); // console.log(multiDayPlaceHFactor, 'Height factor'); // // console.log(eventsIndexes, 'event indexes'); // }, [weekDates, showAllMultiDEvents]); console.log(multiDayPlaceHFactor, 'height factor'); return ( <React.Fragment> <div className="w-100"> <div id="day-layout-table" className="mt-3"> <table className="e-schedule-table border mb-0"> <tbody> <tr> <td> <div className="e-date-header-container"> <div className="e-date-header-wrapper"> <table className="e-schedule-table"> <colgroup> <col></col> <col></col> <col></col> <col></col> <col></col> <col></col> <col></col> </colgroup> <thead> <tr> {(weekDates || []).map((e) => { const today = e; const eachFirstDayInCalcRow = isSameDay( weekDates[0], today ) ? today : null; const todayEvents = events.filter( (e: { startDate: number | Date; endDate: number | Date; }) => (eachFirstDayInCalcRow && areIntervalsOverlapping( { start: e.startDate, end: e.endDate, }, { start: startOfDay(today), end: endOfDay(today), } ) && differenceInDaysOmitTime( new Date(e.startDate), new Date(e.endDate) ) > 1) || (isSameDay(e.startDate, today) && differenceInDaysOmitTime( new Date(e.startDate), new Date(e.endDate) ) > 1) ); // console.log(todayEvents, 'today events'); const prevNextEvents = events.filter((e) => { const isWithinToday = areIntervalsOverlapping( { start: e.startDate, end: e.endDate, }, { start: startOfDay(today), end: endOfDay(today), } ) && differenceInDaysOmitTime( e.startDate, e.endDate ) > 1; return isWithinToday; }); ///////////////////////////////// ///////////////////////////////// / HERE IS THE UPDATE VALUE CODE / ///////////////////////////////// ///////////////////////////////// if ( prevNextEvents.length > multiDayPlaceHFactor.current ) multiDayPlaceHFactor.current = prevNextEvents.length; ///////////////////////////////// ///////////////////////////////// / HERE IS THE UPDATE VALUE CODE / ///////////////////////////////// ///////////////////////////////// let eventsIndexes: any = []; return ( <td className="e-all-day-appointment-wrapper" key={uuid()} > <RenderMultidayEvents multiDayEvents={todayEvents} prevNextEvents={prevNextEvents} showMultiDEvents={showAllMultiDEvents} eventsIndexes={eventsIndexes} weekStart={startOfDay(weekDates[0])} weekEnd={endOfDay( weekDates[weekDates.length - 1] )} /> {prevNextEvents.length > 2 && !showAllMultiDEvents && ( <div className="px-1"> <button onClick={() => setShowMultiDEvents( !showAllMultiDEvents ) } className="e-more-indicator fs-7 btn btn-secondary p-1 w-100 text-start position-absolute" data-count="1" data-group-index="0" style={{ top: `${3 * 32}px`, left: 0, }} > +{prevNextEvents.length - 2} more </button> </div> )} </td> ); })} </tr> </thead> <tbody> <tr></tr> <tr className="e-header-row"> {(weekDates || []).map((date, i) => ( <td colSpan={1} key={uuid()} className={ isSameDay(date, currentDate) ? 'fw-normal text-center align-middle text-Capitalize text-primary border-start' : 'fw-normal text-center align-middle text-Capitalize border-start' } style={{ width: '116.6px' }} > <div className="e-header-cells"> {format(date, 'd EEE')} </div> </td> ))} </tr> <tr className="e-all-day-cells"> {(weekDates || []).map((e) => { return ( <td key={uuid()} style={{ height: `${computeMultiDPHeight( multiDayPlaceHFactor.current )}px`, }} className="border-start" > <div></div> </td> ); })} </tr> </tbody> </table> </div> </div> </td> </tr> <tr> <td> <div style={{ height: DEFAULT_SHEDULAR_HEIGHT }} className="e-time-cells-wrap" > <table> <tbody> {(hours || []).map((time, idx) => ( <tr key={uuid()}> <td style={{ height: CELL_HEIGHT }} className="calendar-td calendar-td-w border-top py-0 align-middle" > <span className="fs-7"> {format(time, 'h:mm a', { locale: enUS })} </span> </td> </tr> ))} </tbody> </table> </div> </td> <td> <div style={{ height: DEFAULT_SHEDULAR_HEIGHT }} className="e-content-wrap" > <table className="e-schedule-table"> <colgroup> <col></col> <col></col> <col></col> <col></col> <col></col> <col></col> <col></col> </colgroup> <thead> <tr> {(weekDates || []).map((date, i) => ( <td key={uuid()} className="e-day-wrapper overflow-visible" > <div className="e-appointment-wrapper"> <RenderEvents day={date} events={getAppointmentsByDates(date, events)} /> </div> </td> ))} </tr> </thead> <tbody> {(hours || []).map((time, idx) => ( <tr key={idx}> {(weekDates || []).map((date) => ( <td key={uuid()} aria-label={date.toISOString()} style={{ height: CELL_HEIGHT }} className="calendar-td calendar-td-w border-start border-top text-nowrap day-time-w fs-8 py-0 align-middle" ></td> ))} </tr> ))} </tbody> </table> </div> </td> </tr> </tbody> </table> </div> </div> </React.Fragment> ); };
相关实现截图:

内容的提问来源于stack exchange,提问作者Owais Ahmed
相关产品推荐
相关产品推荐

