Skip to content

Commit b8368f9

Browse files
feat: starting to hooks to avoid deprecation warnings (bigcalendar#1687)
* feat(hooks): add react hooks rules and plugins to eslint * feat(hooks): upgrade react and react-dom * feat(hooks): update Agenda.js to hooks * feat(hooks): unnecessary line specified react-hooks plugin * feat(hooks): destructuring props on top level
1 parent 62132eb commit b8368f9

4 files changed

Lines changed: 120 additions & 96 deletions

File tree

.eslintrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ parser: babel-eslint
22
extends:
33
- jason/react
44
- prettier
5+
plugins:
6+
- react-hooks
57
env:
68
es6: true
79
rules:
@@ -15,3 +17,5 @@ rules:
1517
varsIgnorePattern: ^_,
1618
argsIgnorePattern: ^_,
1719
}]
20+
react-hooks/rules-of-hooks: error
21+
react-hooks/exhaustive-deps: warn

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"eslint-import-resolver-webpack": "^0.10.1",
9696
"eslint-plugin-import": "^2.14.0",
9797
"eslint-plugin-react": "^7.11.1",
98+
"eslint-plugin-react-hooks": "^4.0.4",
9899
"font-awesome": "^4.7.0",
99100
"globalize": "^0.1.1",
100101
"husky": "^0.14.3",
@@ -108,10 +109,10 @@
108109
"postcss": "^7.0.16",
109110
"postcss-cli": "^6.1.2",
110111
"prettier": "^1.15.1",
111-
"react": "^16.6.1",
112+
"react": "^16.13.1",
112113
"react-bootstrap": "^0.32.4",
113114
"react-docgen": "^3.0.0-rc.1",
114-
"react-dom": "^16.6.1",
115+
"react-dom": "^16.13.1",
115116
"react-tackle-box": "^2.1.0",
116117
"rimraf": "^2.4.2",
117118
"rollup": "^1.1.0",

src/Agenda.js

Lines changed: 79 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import PropTypes from 'prop-types'
2-
import React from 'react'
2+
import React, { useRef, useEffect } from 'react'
33
import addClass from 'dom-helpers/addClass'
44
import removeClass from 'dom-helpers/removeClass'
55
import getWidth from 'dom-helpers/width'
@@ -10,75 +10,28 @@ import { navigate } from './utils/constants'
1010
import { inRange } from './utils/eventLevels'
1111
import { isSelected } from './utils/selection'
1212

13-
class Agenda extends React.Component {
14-
constructor(props) {
15-
super(props)
16-
this.headerRef = React.createRef()
17-
this.dateColRef = React.createRef()
18-
this.timeColRef = React.createRef()
19-
this.contentRef = React.createRef()
20-
this.tbodyRef = React.createRef()
21-
}
22-
23-
componentDidMount() {
24-
this._adjustHeader()
25-
}
26-
27-
componentDidUpdate() {
28-
this._adjustHeader()
29-
}
30-
31-
render() {
32-
let { length, date, events, accessors, localizer } = this.props
33-
let { messages } = localizer
34-
let end = dates.add(date, length, 'day')
35-
36-
let range = dates.range(date, end, 'day')
37-
38-
events = events.filter(event => inRange(event, date, end, accessors))
39-
40-
events.sort((a, b) => +accessors.start(a) - +accessors.start(b))
41-
42-
return (
43-
<div className="rbc-agenda-view">
44-
{events.length !== 0 ? (
45-
<React.Fragment>
46-
<table ref={this.headerRef} className="rbc-agenda-table">
47-
<thead>
48-
<tr>
49-
<th className="rbc-header" ref={this.dateColRef}>
50-
{messages.date}
51-
</th>
52-
<th className="rbc-header" ref={this.timeColRef}>
53-
{messages.time}
54-
</th>
55-
<th className="rbc-header">{messages.event}</th>
56-
</tr>
57-
</thead>
58-
</table>
59-
<div className="rbc-agenda-content" ref={this.contentRef}>
60-
<table className="rbc-agenda-table">
61-
<tbody ref={this.tbodyRef}>
62-
{range.map((day, idx) => this.renderDay(day, events, idx))}
63-
</tbody>
64-
</table>
65-
</div>
66-
</React.Fragment>
67-
) : (
68-
<span className="rbc-agenda-empty">{messages.noEventsInRange}</span>
69-
)}
70-
</div>
71-
)
72-
}
73-
74-
renderDay = (day, events, dayKey) => {
75-
let {
76-
selected,
77-
getters,
78-
accessors,
79-
localizer,
80-
components: { event: Event, date: AgendaDate },
81-
} = this.props
13+
function Agenda({
14+
selected,
15+
getters,
16+
accessors,
17+
localizer,
18+
components,
19+
length,
20+
date,
21+
events,
22+
}) {
23+
const headerRef = useRef(null)
24+
const dateColRef = useRef(null)
25+
const timeColRef = useRef(null)
26+
const contentRef = useRef(null)
27+
const tbodyRef = useRef(null)
28+
29+
useEffect(() => {
30+
_adjustHeader()
31+
})
32+
33+
const renderDay = (day, events, dayKey) => {
34+
const { event: Event, date: AgendaDate } = components
8235

8336
events = events.filter(e =>
8437
inRange(e, dates.startOf(day, 'day'), dates.endOf(day, 'day'), accessors)
@@ -117,9 +70,7 @@ class Agenda extends React.Component {
11770
style={userProps.style}
11871
>
11972
{first}
120-
<td className="rbc-agenda-time-cell">
121-
{this.timeRangeLabel(day, event)}
122-
</td>
73+
<td className="rbc-agenda-time-cell">{timeRangeLabel(day, event)}</td>
12374
<td className="rbc-agenda-event-cell">
12475
{Event ? <Event event={event} title={title} /> : title}
12576
</td>
@@ -128,9 +79,7 @@ class Agenda extends React.Component {
12879
}, [])
12980
}
13081

131-
timeRangeLabel = (day, event) => {
132-
let { accessors, localizer, components } = this.props
133-
82+
const timeRangeLabel = (day, event) => {
13483
let labelClass = '',
13584
TimeComponent = components.time,
13685
label = localizer.messages.allDay
@@ -164,27 +113,25 @@ class Agenda extends React.Component {
164113
)
165114
}
166115

167-
_adjustHeader = () => {
168-
if (!this.tbodyRef.current) return
116+
const _adjustHeader = () => {
117+
if (!tbodyRef.current) return
169118

170-
let header = this.headerRef.current
171-
let firstRow = this.tbodyRef.current.firstChild
119+
let header = headerRef.current
120+
let firstRow = tbodyRef.current.firstChild
172121

173122
if (!firstRow) return
174123

175124
let isOverflowing =
176-
this.contentRef.current.scrollHeight >
177-
this.contentRef.current.clientHeight
178-
let widths = this._widths || []
179-
180-
this._widths = [
181-
getWidth(firstRow.children[0]),
182-
getWidth(firstRow.children[1]),
183-
]
184-
185-
if (widths[0] !== this._widths[0] || widths[1] !== this._widths[1]) {
186-
this.dateColRef.current.style.width = this._widths[0] + 'px'
187-
this.timeColRef.current.style.width = this._widths[1] + 'px'
125+
contentRef.current.scrollHeight > contentRef.current.clientHeight
126+
127+
let _widths = []
128+
let widths = _widths
129+
130+
_widths = [getWidth(firstRow.children[0]), getWidth(firstRow.children[1])]
131+
132+
if (widths[0] !== _widths[0] || widths[1] !== _widths[1]) {
133+
dateColRef.current.style.width = _widths[0] + 'px'
134+
timeColRef.current.style.width = _widths[1] + 'px'
188135
}
189136

190137
if (isOverflowing) {
@@ -194,6 +141,46 @@ class Agenda extends React.Component {
194141
removeClass(header, 'rbc-header-overflowing')
195142
}
196143
}
144+
145+
let { messages } = localizer
146+
let end = dates.add(date, length, 'day')
147+
148+
let range = dates.range(date, end, 'day')
149+
150+
events = events.filter(event => inRange(event, date, end, accessors))
151+
152+
events.sort((a, b) => +accessors.start(a) - +accessors.start(b))
153+
154+
return (
155+
<div className="rbc-agenda-view">
156+
{events.length !== 0 ? (
157+
<React.Fragment>
158+
<table ref={headerRef} className="rbc-agenda-table">
159+
<thead>
160+
<tr>
161+
<th className="rbc-header" ref={dateColRef}>
162+
{messages.date}
163+
</th>
164+
<th className="rbc-header" ref={timeColRef}>
165+
{messages.time}
166+
</th>
167+
<th className="rbc-header">{messages.event}</th>
168+
</tr>
169+
</thead>
170+
</table>
171+
<div className="rbc-agenda-content" ref={contentRef}>
172+
<table className="rbc-agenda-table">
173+
<tbody ref={tbodyRef}>
174+
{range.map((day, idx) => renderDay(day, events, idx))}
175+
</tbody>
176+
</table>
177+
</div>
178+
</React.Fragment>
179+
) : (
180+
<span className="rbc-agenda-empty">{messages.noEventsInRange}</span>
181+
)}
182+
</div>
183+
)
197184
}
198185

199186
Agenda.propTypes = {

yarn.lock

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5065,6 +5065,11 @@ eslint-plugin-import@^2.14.0:
50655065
read-pkg-up "^2.0.0"
50665066
resolve "^1.10.0"
50675067

5068+
eslint-plugin-react-hooks@^4.0.4:
5069+
version "4.0.4"
5070+
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.4.tgz#aed33b4254a41b045818cacb047b81e6df27fa58"
5071+
integrity sha512-equAdEIsUETLFNCmmCkiCGq6rkSK5MoJhXFPFYeUebcjKgBmWWcgVOqZyQC8Bv1BwVCnTq9tBxgJFgAJTWoJtA==
5072+
50685073
eslint-plugin-react@^7.11.1:
50695074
version "7.13.0"
50705075
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz#bc13fd7101de67996ea51b33873cd9dc2b7e5758"
@@ -10691,7 +10696,17 @@ react-docgen@^3.0.0, react-docgen@^3.0.0-rc.1:
1069110696
node-dir "^0.1.10"
1069210697
recast "^0.16.0"
1069310698

10694-
react-dom@^16.6.1, react-dom@^16.8.1:
10699+
react-dom@^16.13.1:
10700+
version "16.13.1"
10701+
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
10702+
integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==
10703+
dependencies:
10704+
loose-envify "^1.1.0"
10705+
object-assign "^4.1.1"
10706+
prop-types "^15.6.2"
10707+
scheduler "^0.19.1"
10708+
10709+
react-dom@^16.8.1:
1069510710
version "16.8.6"
1069610711
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
1069710712
integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
@@ -10874,7 +10889,16 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0:
1087410889
prop-types "^15.6.2"
1087510890
react-lifecycles-compat "^3.0.4"
1087610891

10877-
react@^16.6.1, react@^16.8.1:
10892+
react@^16.13.1:
10893+
version "16.13.1"
10894+
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
10895+
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
10896+
dependencies:
10897+
loose-envify "^1.1.0"
10898+
object-assign "^4.1.1"
10899+
prop-types "^15.6.2"
10900+
10901+
react@^16.8.1:
1087810902
version "16.8.6"
1087910903
resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
1088010904
integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
@@ -11654,6 +11678,14 @@ scheduler@^0.13.6:
1165411678
loose-envify "^1.1.0"
1165511679
object-assign "^4.1.1"
1165611680

11681+
scheduler@^0.19.1:
11682+
version "0.19.1"
11683+
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
11684+
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
11685+
dependencies:
11686+
loose-envify "^1.1.0"
11687+
object-assign "^4.1.1"
11688+
1165711689
schema-utils@^0.4.5:
1165811690
version "0.4.7"
1165911691
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"

0 commit comments

Comments
 (0)