Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use React to make a schedule component

2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article focuses on "how to use React to play a schedule component", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to use React to make a schedule component".

Directory structure

└─ Calendar

│ data.d.ts type definition file

│ index.tsx entry file

├─ components

│ ├─ CalendatrHeader header Container component

│ index.less

│ index.tsx

│ │ │

│ │ └─ components

│ │ ├─ DailyOptions Top switch date and switch Mode status component

│ index.less

│ index.tsx

│ │ │

│ │ └─ WeeklyOptions Weekly Mode date and week component

│ │ index.less

│ │ index.tsx

│ │

│ ├─ Container Container components

│ │ Container.tsx

│ │ index.less

│ │

│ ├─ ScheduleCantainer lower half schedule container

│ │ index.less

│ │ index.tsx

│ │

│ └─ ScheduleItem gray section of each schedule component

│ index.less

│ index.tsx

└─ utils

Index.ts tool file

? Split component

If you look at the picture carefully, it is not difficult to see that I have split it into three parts on a large chunk of the component:

Container container: this component is the container of the entire component. It is responsible for UI core state data and maintains two states:

TargetDay: date and time stamp is currently selected (why timestamp is selected for later explanation)

SwitchWeekAndDay: save the status of the day and week

CalendatrHeader header container component: a subcomponent of the Container container, which is responsible for switching dates and changing the state of the week and day of the component; this component contains a calendar component, a week component, a date filter component, a day and week toggle component, a today button component, and finally a businessRender for a business component.

ScheduleCantainer schedule container component: this component is supported by 25 scheduleRender components (because it is between 0: 00 today and 0: 00 am the next morning), and the sub-component also includes a timescale component.

ScheduleRender: specifically speaking about this component, this component accepts a callback, and the callback returns a JSX, which is the custom style calendar component passed in by the caller (details will be discussed later)

This is the general component split, the text expression is really poor, can be combined with picture YY

Let's do it next!

Code implementation

First, take a look at the accepted parameter type definitions:

Type dataType = {startTime: DOMTimeSt / / start timestamp endTime: DOMTimeSt / / end timestamp [propsName: string]: any; / / Business data}; type ContainerType = {data: dataType []; / / Business data initDay?: DOMTimeSt / / initialization timestamp onChange?: (params: DOMTimeStamp) = > void; / / onChange method height?: number when changing the date / / the height scheduleRender?: of the ScheduleCantainer container ({data: dataType, timestampRange: [DOMTimeStamp, DOMTimeStamp],}) = > JSX.Element; / / the callback passed in will receive the business data of the current data and the timestamp range of the current business data; businessRender?: ({timestamp: DOMTimeStamp}) = > React.ReactNode / / query the Cai Xukun at the front end of the incoming business component. Look at the picture. Do you remember? Mode?: "day" | "week"; / / initialize the mode of display day and day}; Container container component

Code:

Const Container: React.FC = ({initDay, onChange, scheduleRender, businessRender, data, height = "day",}) = > {/ / currently selected date and time stamp const [targetDay, setTargetDay] = useState (initDay); / / switch day and week const [switchWeekandDay, setSwitchWeekandDay] = useState (mode); return ({onChange (timestamp); setTargetDay (timestamp)) } businessRender= {businessRender} switchWeekandDay= {switchWeekandDay} setSwitchWeekandDay= {setSwitchWeekandDay} / >);}

If you look at the code, you can think about it. You must raise the global state data to the highest level to control, which is also in line with React's component design philosophy.

The current timestamp and daily / weekly status are maintained, and the states of all subcomponents are displayed according to targetDay

CalendatrHeader header Container component

I think the other head containers are fine, because the week is written to death (mainly referring to the Apple calendar component, Apple's week has not been changed, so refer to the excellent design of the big factory). So the more important thing to knock on the head is how to accurately display the date of the week.

In fact, I wrote two ways to show the date of the week:

The first is to take the week of the current date as the basis, calculate forward and backward respectively, and finally output a List like [29, 30, 31, 1, 2, 3, 4]. If today happens to be the 1st or 2nd, go ahead and subtract the date of the last day of last month.

The second way is the following code, which is to locate the week of the current date and dynamically calculate it through the timestamp. As long as you know how to subtract a few days forward and add a few days later.

In fact, both ways are fine. In the end, I used the second, which is obviously more concise.

As shown below:

Output in the current week [12, 13, 14, 15, 16, 17, 18]

The following is the code for the implementation of the above difficulties:

Const calcWeekDayList: (params: number) = > WeekType = (params) = > {const result = []; for (let I = 1; I

< weekDay(params); i++) { result.unshift(params - 3600 * 1000 * 24 * i); } for (let i = 0; i < 7 - weekDay(params) + 1; i++) { result.push(params + 3600 * 1000 * 24 * i); } return [...result] as WeekType; }; 代码: const CalendatrHeader: React.FC = ({ targetDay, setTargetDay, switchWeekandDay, businessRender, setSwitchWeekandDay,}) =>

{/ / the date of the current week const [dateTextList, setDateTextList] = useState ([]); / / this status is when switching weeks, directly increase or decrease the timestamp of one week, and the date of the next week or the previous week will be calculated automatically; const [currTime, setCurrTime] = useState (targetDay); useEffect () = > {setDateTextList (calcWeekDayList (targetDay));}, [targetDay]) / / the date before and after the day is calculated according to the current timestamp. Since the week is fixed, just calculate the date of the current week const calcWeekDayList: (params: number) = > WeekType = (params) = > {const result = []; for (let I = 1; I)

< weekDay(params); i++) { result.unshift(params - 3600 * 1000 * 24 * i); } for (let i = 0; i < 7 - weekDay(params) + 1; i++) { result.push(params + 3600 * 1000 * 24 * i); } return [...result] as WeekType; }; const onChangeWeek: (type: "prevWeek" | "nextWeek", switchWay: "week" | "day") =>

Void = (type, switchWay,) = > {if (switchWay = "week") {const calcWeekTime = type = = "prevWeek"? CurrTime-3600 * 1000 * 24 * 7: currTime + 3600 * 1000 * 24 * 7; setCurrTime (calcWeekTime); setDateTextList ([... calcWeekDayList (calcWeekTime)]);} if (switchWay = = "day") {const calcWeekTime = type = = "prevWeek"? TargetDay-3600 * 1000 * 24: targetDay + 3600 * 1000 * 24; setCurrTime (calcWeekTime); setTargetDay (calcWeekTime);}}; return ({setSwitchWeekandDay (value); if (value = "week") {setDateTextList (calcWeekDayList (targetDay) } onChangeWeek= {(type) = > onChangeWeek (type, switchWeekandDay)} / > {switchWeekandDay = "week" & & ()} GMT+8 {businessRender ({timestamp: targetDay})});}

DailyOptions: it's actually a container for headers to switch between "date of the week" & "Day and week" & "Today" components.

WeeklyOptions: this is the following component that shows the day and date of the current week. If you switch to day, it will not be shown.

BusinessRender: this is the business component passed in by the users in the column of brother Xiao Zhan

ScheduleCantainer detailed schedule container

Left scale

The left scale is actually written dead from 00:00 to 01:00-> 23:00-00:00, but there is a small problem when writing, that is, this component floats to the left, and it scrolls as the item on the right scrolls. In fact, I wrote in a box at the beginning, and the rolling container scrolled together, but encountered a small problem. Because the entry on the right becomes ultra-wide, a horizontal scroll bar appears, and the left timescale is scrolled out of the visual area if you scroll the entire container.

So after absolute positioning, listen to the scrolling event of the calendar entry on the right, dynamically change the top value of the style on the left, and assign the value in reverse. Because it is scrolling down, the time scale on the left needs to be scrolled up, so the inversion of the top value will achieve the effect of synchronization; what a smart guy, huh? This code does not take up space, everyone is free to play it, if there is a better way, welcome to leave a comment.

ScheduleItem schedule Container entry

Let's take a look at the code for this component:

Const ScheduleItem: React.FC = ({timestampRange, dataItem, scheduleRender, width, dataItemLength,}) = > {/ / calculate container height const calcHeight: (timestampList: [number, number]) = > number = (timestampList) = > timestampList.length > 1? (timestampList [1]-timestampList [0]) / 1000 / 60 / 2: 30; const calcTop: (startTime: number) = > number = (startTime) = > moment (startTime). Minute () / 2; / / calculate ScheduleItem width const calcWidth: (w: number, d: number) = > string = (w, d) = > width = = 0 | dataItemLength * width

< 347 ? "100%" : `${d * w}px`; return ( {dataItem.map((data, index) =>

{return ({data.startTime > = timestampRange [0] & & data.startTime

< timestampRange[1] && ( {scheduleRender({ data, timestampRange })} )} ); })} );}; 这一部分呢(就是下面灰色一条一条的部分), 为什么要单独出一个组件呢? 可以先思考一下...... 好了, 不卖关子了, 其实就是为了好定位用户的日程数据, 例如今天的10:00 -- 11:00, 定位到哪里的问题. 还记得这个API吗? scheduleRender?: ({ data: dataType, timestampRange: [DOMTimeStamp, DOMTimeStamp], }) =>

JSX.Element

In this component, there will be a parameter like [DOMTimeStamp, DOMTimeStamp] (meaning DOMTimeStamp timestamp). These two timestamps are actually 10:00-11:00 timestamps of the current period and ending timestamps. Because the startTime and endTime we accept are also timestamps, you can control whether the timestamps are displayed and hidden by comparing whether the size is in this range. This time you can understand why you use timestamps. Just compare the size of the numbers directly.

Let's talk about the style of this thing again:

In fact, I wrote this thing 30px, the reason is because an hour is 60 minutes, if 60px is too high, so write 30px, easy to locate, after all, I am lazy, do not want too complicated calculation

So the positioning calculation is only one line of code: const calcTop: (startTime: number) = > number = (startTime) = > moment (startTime). Minute () / 2; the height positioning problem is over! Haha ~ ~

Next, another problem is the question of height, as shown in the figure:

In fact, it is not difficult to calculate the height. It is mainly calculated according to the range of the current start and end time (1px 2 minutes). The specific implementation depends on the code:

Const calcHeight: (timestampList: [number, number]) = > number = (timestampList) = > timestampList.length > 1? (timestampList [1]-timestampList [0]) / 1000 / 60 / 2: 30

First of all, we will determine whether the timestamp of the input parameter is only one time. If there is only a start time and no end time, write 30px. If there is a start and end time, change it to minutes and calculate it dynamically.

Finally, there is the question of how the business data is transmitted and how it is rendered to the component:

First, take a look at the JSON that we passed in the data field:

[{startTime: 1626057075000, / / start time endTime: 1626070875000, / / end time value: "any", / / Business data}, {startTime: 1626057075000, endTime: 1626070875000, value: "any",}, {startTime: 1626057075000, endTime: 1626070875000, value: "any",}, {startTime: 1626057075000, endTime: 1626070875000, value: "any",},]

In fact, when rendering this ScheduleItem component in a loop, we use the 24-hour list to loop. Then, during the cycle, we dynamically go to the business data to find the business data within the time range of the current cycle, and insert this data into the component. The approximate code is as follows:

For (let I = 0; I

< HoursList.length; i++) { resule.push({ timestampRange: [todayTime + i * 3600 * 1000, todayTime + (i + 1) * 3600 * 1000], dataItem: [ // 由于当前一个时间段, 日程可能冲突, 所以要有一个list传入组件 ...data.filter((item) =>

{return (item.startTime > = todayTime + I * 3600 * 1000 & & item.startTime < todayTime + (I + 1) * 3600 * 1000);}),],}); at this point, I believe you have a better understanding of "how to use React to create a calendar component". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report