-
Notifications
You must be signed in to change notification settings - Fork 16
/
react.javascript.txt
996 lines (870 loc) · 67.9 KB
/
react.javascript.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
REACT
REACT
REACTDOM #Two packages (versions 15.4.2) (started documenting 15.5.0 but did not finish) (should also check create-react-class module). Must require both.
REACTDOMSERVER #Subpackage of REACTDOM, for using in the server
DEVELOPMENT MODE ==> #Checks NODE_ENV !== 'production'.
#React uses envify in release files, which replaces NODE_ENV by 'development|production'
/=+===============================+=\
/ : : \
)==: THEORY :==(
\ :_______________________________: /
\=+===============================+=/
PRINCIPLE ==> #Data flow:
# - one-way direction (parent to children):
# - communicating with parent: passing a FUNC (e.g. REACTLINK) as props
# - 'state' is state owned by current RCOMP, 'props' is state owned by a parent
# - when changing 'state':
# - current RCOMP gets 'updated'
# - children get 'updated' (if same RTYPE) or 'unmounted|mounted' (if different RTYPE)
# - smart vs dumb RCOMP:
# - smart components / 'containers':
# - manipulate state:
# - have 'state', passed to children as props
# - pass Flux actions callbacks to children
# - not visual, e.g. no CSS nor DOM
# - should be as few as possible
# - dumb / 'presentational' components:
# - manipulate UI:
# - no 'state'
# - reusable, so no dependency (e.g. no Flux actions nor dispatch)
# - reduce amount of 'state':
# - not computed|duplicated from other 'state|props'
# - e.g. getInitialState() should not use props
# - not complex (e.g. not RELEM)
# - 'context':
# - like 'props' but with less typing
# - should only be used for 'props' that are used everywhere in the app, e.g. current user, design theme, etc.
# - should use explicit 'props' otherwise
# - children are owned by the RCOMP that create them:
# - i.e. in RCOMP.render() -> <RCOMP2>...</RCOMP2>, ... will be 'updated' when current RCOMP is,
# but not when RCOMP2 is, except if cloned in RCOMP2.render()
# - will still be correctly 'mounted|unmounted'
#Virtual DOM:
# - provides abstraction (e.g. can be used on server without real DOM)
# - allows faster diff algorithm
# - problem: makes it harder to reach to actual DOM
#JSX: mixing templates into JavaScript because they belong together
GOOD PRACTICES ==> # - when passing props down, should explicitely pass props that are consumed, e.g. deconstructing then spreading:
# let [ VAR, OBJ... ] = this.props;
# // Use VAR
# return <ELEM [VAR={VAR}] {...OBJ}>
BAD PRACTICES ==> # - reaching to HTML elements instead of using RELEM|RCOMP abstraction:
# - e.g. using REF, REACTDOM.findDOMNode()
# - using RCOMP other than as 'this' in RCOMP methods:
# - e.g. using REACTDOM.render() return value
# - shortcircuiting data flow:
# - RCOMP.forceUpdate()
/=+===============================+=\
/ : : \
)==: TERMINOLOGY :==(
\ :_______________________________: /
\=+===============================+=/
RTYPE #RELEM's type
#By convention, custom RTYPE name should be Capitalized
REACT.Component #Base RTYPE
RDOM #Builtin RTYPE representing an HTML 'TAG'
RELEM #Abstracted ELEM (non-instantiated), i.e. RTYPE + props
RNODE #VAL[_ARR...]
# - VAL can be:
# - RELEM
# - STR|NUM: text node. Cannot use HTML entities, but can use raw|escaped Unicode.
# - null|undefined|true|false: no node (but present in props.children as null)
# - can be ARR, or ARR_ARR, etc. (will be flattened)
RCOMP #Instantiated RELEM. Is not an ELEM.
/=+===============================+=\
/ : : \
)==: RTYPE :==(
\ :_______________________________: /
\=+===============================+=/
REACT.createClass(OBJ) #Creates and returns a RTYPE
#Bind all OBJ.FUNC's this to current RCOMP
#OBJ is merged into RCOMP's prototype
STATELESS COMPONENT ==> #Can use a FUNC()->RELEM as RTYPE:
# - like specifying only OBJ.render(), with also:
# - can specify FUNC.contextTypes OBJ
# - REF is null, so:
# - cannot use findDOMNode()
# - cannot use props.ref
ES6 CLASSES ==> #Can create ES6 class derived from REACT.Component as an alternative to REACT.createClass()
#Preferred.
#Differences:
# - different syntax:
# - getInitialState() -> setting this.state in constructor
# - propTypes OBJ -> static propTypes OBJ
# - getDefaultProps()->OBJ -> static defaultProps OBJ
# - less functionalities:
# - no 'this' binding
# - cannot use mixins
# - cannot use RCOMP.replaceState|isMounted()
RCOMP.displayName #JSX tag name, used for debugging (should be in dev only)
#Deduced from assigned variable if using Babel plugin "react-display-name"
/=+===============================+=\
/ : : \
)==: RELEM :==(
\ :_______________________________: /
\=+===============================+=/
REACT.createElement #Creates and returns a RELEM
('TAG'|RTYPE[, OBJ][, RNODE...]) #OBJ|RNODE... are RCOMP.props|children.
#'TAG':
# - use corresponding RDOM
# - RCOMP.props|children -> HTML attributes|children
REACT.createFactory('TAG'|RTYPE) #Similar to REACT.createElement.bind(null, 'TAG'|RTYPE)
REACT.DOM.TAG(...) #Same as REACT.createElement('TAG', ...)
REACT.cloneElement #Creates and returns a RELEM2, cloned from RELEM.
(RELEM[, OBJ][, RNODE...]) #OBJ are shallow merged, RNODE... children are replaced.
RELEM.type #'TAG'|RTYPE
REACT.isValidElement(VAL) #True if RELEM
/=+===============================+=\
/ : : \
)==: RENDER :==(
\ :_______________________________: /
\=+===============================+=/
REACTDOM.render #ELEM's children = RELEM2's instantiation
(RELEM2, ELEM[, FUNC()])->REF #If ELEM children already contains older RELEM:
# - RELEM === RELEM2 (i.e. same reference): nothing happens
# - RELEM == RELEM2 (i.e. same RTYPE): 'update' RELEM
# - RELEM != RELEM2 (i.e. different RTYPE): 'unmount' RELEM, 'mount' RELEM2
#Calls FUNC() after all events done.
#Rendering adds React-specific HTML attributes:
# - e.g. data-reactid, data-react-checksum, data-reactroot
# - if RELEM does not have them (i.e. has not been previously rendered by React), will
# 'unmount|mount' instead of 'update'
REACTDOMSERVER.renderToString #Returns RELEM as 'HTML'
(RELEM) #Idea is pre-render on the server:
# - why:
# - when client calls REACTDOM.render(), there is less DOM update, making initial load time faster
# - more SEO-friendly
# - requires code to be both client and server ('universal app')
# - 'HTML' includes React-specific HTML attributes
#Server should be able to just render the component by reusing components client code:
# - components must use code that can be loaded on both the client and server
# - component props must be calculated server-side, so AJAX requests must work on both the client and Node
REACTDOMSERVR.renderToStaticMarkup#Same but does not include React-specific HTML attributes.
(RELEM) #To use if rendered 'HTML' will not be loaded in client-side React.
MOUNT ==> #Fired on:
# - parent rendered with different RTYPE, for new RELEM2
# - first render()
#Fires RCOMP2 (in order):
# - componentWillMount()
# - render()
# - componentDidMount()
UPDATE ==> #Fired on:
# - parent rendered with same RTYPE but different props
# - RCOMP.setState()
# - RCOMP.forceUpdate()
#Not fired if an 'update' is already ongoing
#Does:
# - not create new RCOMP (only updates it)
# - replace RCOMP's props with RCOMP2's
# - fires RCOMP (in order):
# - componentWillReceiveProps(OBJ2, OBJ4):
# - not fired by RCOMP.setState() nor RCOMP.forceUpdate()
# - before assigning props (this.props is still old one)
# - OBJ2|OBJ4 is next props|context
# - often used to call setState() according to props
# - shouldComponentUpdate(OBJ2, OBJ3, OBJ4)->BOOL:
# - not fired by RCOMP.forceUpdate()
# - return false if nothing was changed, so we stop here and avoid to:
# - fire componentWillUpdate|DidUpdate(), which might do more
# - fire render():
# - since render() would render same DOM, then no DOM manipulation would done anyway.
# - however this saves the time spent by JavaScript to check it
# - is optional and for performance purpose
# - OBJ2|OBJ3|OBJ4 is next props|state|context
# - React.PureComponent is like React.Component except:
# - it defines shouldComponentUpdate() doing shallow comparison of props|state
# - to use if:
# - props|state|context can be shallow compared (i.e. contain objects)
# - render() only depends on props|state|context
# - componentWillUpdate(OBJ2, OBJ3, OBJ4)
# - cannot use setState()
# - OBJ2|OBJ3|OBJ4 is next props|state|context
# - render()
# - componentDidUpdate(OBJ2, OBJ3, OBJ4)
# - OBJ2|OBJ3|OBJ4 is prev props|state|context
UNMOUNT ==> #Fired on:
# - parent rendered with different RTYPE, for old RELEM
# - REACTDOM.unmountComponentAtNode()
#Fires RCOMP:
# - componentWillUnmount()
RCOMP.render() #Does the actual DOM manipulation.
#Must return RCOMP's single child, i.e. RELEM (or null|false):
# - calls REACTDOM.render() on child recursively:
# - order:
# - start with ancestor for componentWill*(), shouldComponentUpdate(), render()
# - start with descendant for componentDid*()
# - compare children old RELEM with new RELEM2 according to DOM order
# - problem:
# - in lists of similar items, modifications might recreate all items
# (e.g. prepending, since it compares by DOM order)
# - this is bad for performance, but also does not retain state in those items
# - solution:
# - can use HTML attribute 'key', which will then be used for comparison
# - should then be unique ID among siblings
## - CREATEFRAGMENT({ VAR: RNODE ... })->RNODE_ARR:
## - returns all RNODE concatenated
## - assigns each RNODE.key = 'VAR/.NUM[$KEY]' where:
## - NUM is element index in RNODE (which can be an array)
## - KEY is RNODE.key
## - package 'react-addons-create-fragment' (same version as React)
# - if children are not newly created in render() (e.g. use props.children reference),
# old RELEM === new RELEM2, so nothing will happen for that child
# - i.e. RCOMP 'owns' the children it creates in render(), but not the children passed to it
# - if RDOM, will update DOM, but in an efficient way:
# - does not update if same
# - only add|remove attributes if only attributes changed
# - should not modify state nor read global state nor be async
# (use componentDidMount|Update() for that)
#Single child, i.e. must return RELEM, not RELEM_ARR
RCOMP.forceUpdate() #Forces 'update'
#Useful when render() depends on state that changed but did not trigger a new render(), e.g.:
# - RCOMP.state.OBJ.VAR changed, but no setState() was called
# - DOM element change that cannot be caught with onEvent
REACTDOM.unmountComponentAtNode #Inverse of REACTDOM.render(): remove ELEM children (firing 'unmount') then returns true.
(ELEM) #If no RCOMP was mounted, does nothing and returns false.
RCOMP.isMounted() #To use in async operation to make sure RCOMP still exists.
/=+===============================+=\
/ : : \
)==: PROPS/STATE BASE :==(
\ :_______________________________: /
\=+===============================+=/
RCOMP.props #Read-only state OBJ.
#Readonly (non-configurable, non-writable) shallowly (but should be considered deeply readonly)
#'Owned' by a parent, i.e. props change when the parent passing them re-rendered children with different props.
#Rendered as HTML attributes for RDOM
RELEM.props #As opposed to RCOMP, props.key|ref are not on RELEM.props.* but on RELEM.*
RCOMP.getDefaultProps()->OBJ #Called once per RTYPE (not per RCOMP),
#then the result OBJ is shallowingly assigned to each new RCOMP.props
RCOMP.state #Read-write state OBJ
#'Owned' by RCOMP
#Should never be written to:
# - use setState() instead
# - to avoid it, might need to make deep copy, including using tools like immutable-js
#Might be null if not getInitialState()
RCOMP.getInitialState()->OBJ #Initial RCOMP.state
#Called before componentWillMount()
RCOMP.setState(OBJ[(OBJ2, OBJ3)] #Shallow merges into RCOMP.state
[, FUNC()]) #OBJ2|OBJ3 is current state|props
#Might be performed async or not. FUNC() performed afterwards.
#Fires 'update'
RCOMP.replaceState(...) #Same but sets instead of merging
/=+===============================+=\
/ : : \
)==: PROPS/STATE EXTRA :==(
\ :_______________________________: /
\=+===============================+=/
RCOMP.props.children #CHILDREN
#Opaque structure to be manipulated only through React.Children RCHILDREN,
#where RNODE will be individual elements (not ARR)
RCHILDREN.count(CHILDREN) #
RCHILDREN.map|forEach
(CHILDREN, FUNC(RNODE)[, THIS]) #
RCHILDREN.toArray(CHILDREN) #Returns RNODE_ARR
RCHILDREN.only(CHILDREN) #Returns RNODE if CHILDREN contains only one child, and it is a RELEM
#Otherwise throws (if in 'development mode')
React.PropTypes ##PTYPES
##Module 'prop-types' (same version as React)
RCOMP.propTypes #OBJ.VAR PROP_RULE:
# - if RTYPE.props.VAR does not satisfy PROP_RULE during createElement(), it will throw error:
# - only once for a given RTYPE + VAR + PROP_RULE
# - only in 'development mode'
# - use PTYPES.oneOfType or custom PROP_RULE for multiple validations
#PROP_RULE is FUNC(RTYPE.props, 'VAR', 'RTYPE')[->ERROR]
#List of builtin PROP_RULE:
PTYPES.array|bool|func|symbol|
number|object|string|node|element #Checks type: 'node' is RNODE[_ARR], 'element' RELEM
PTYPES.instanceOf(TYPE) #
PTYPES.oneOf(VAL_ARR) #
PTYPES.oneOfType(PROP_RULE_ARR) #
PTYPES.arrayOf(PROP_RULE) #
PTYPES.objectOf(PROP_RULE) #Object values
PTYPES.shape({VAR: PROP_RULE ...})#
PROP_RULE.isRequired #E.g. PTYPES.bool.isRequired
PTYPES.checkPropTypes
(PTYPES.*, RTYPE.props, 'VAR',
'RTYPE')[->ERROR] #Calling manually
RCOMP.mixins #OBJ_ARR, where OBJ gets merged into RCOMP.
#If property conflict:
# - if lifecycle RCOMP.FUNC (e.g. componentWillUpdate, etc.), surcharges instead of
# overriding it (i.e. called before non-mixin one)
# - otherwise, throws error
#Deprecated, prefer high-order-composition/decorators
RCOMP.statics #OBJ assigned to RTYPE during createClass(), i.e. static methods.
/=+===============================+=\
/ : : \
)==: CONTEXT :==(
\ :_______________________________: /
\=+===============================+=/
RCOMP.context #Like RCOMP.props, but with less typing (see getChildContext())
RCOMP.getChildContext()->OBJ #Define|merges RCOMP.context OBJ in all ancestors
RCOMP.contextTypes #Like RCOMP.propTypes but for RCOMP.context, defined in the ancestor using it
#Required.
RCOMP.childContextTypes #Same for the parent defining getChildContext().
#Required.
/=+===============================+=\
/ : : \
)==: REFS :==(
\ :_______________________________: /
\=+===============================+=/
REF #Instantiation of a RELEM:
# - if based on RTYPE, RCOMP
# - if based on 'TAG', ELEM
# - if stateless component, null
RCOMP.props.ref #On createElement():
# - FUNC(REF):
# - on mounting, called once with REF
# - on updating, first called with null (to let handler clean previous
# reference), then called with new REF
# - when unmounting, called once with null
# - 'REF': same as FUNC(REF) { this.refs['REF'] = REF; }
REACTDOM.findDOMNode(RCOMP) #Returns corresponding ELEM
#If RCOMP not mounted, throws exception
/=+===============================+=\
/ : : \
)==: RDOM :==(
\ :_______________________________: /
\=+===============================+=/
RDOM ==> #Builtin RTYPE mimicking usual HTML.
#Differences are below.
ALLOWED HTML TAGS|ATTRIBUTES ==> #Whitelisted:
# - but should cover most standard HTML
# - custom HTML tags are allowed
# - custom HTML attributes are allowed if HTML tag name contains '-' or HTML attribute
# is="..." present
HTML ATTRIBUTES ==> # - camelCased, except data-*, aria-*
# - class -> className, html -> htmlFor
# - values:
# - style.CSSPROP VAL (camelCased, except vendor prefix which are titleized)
# - boolean attributes: must only use BOOL as value
# - NUM -> NUMpx, except where LENP is not expected
# - new:
# - dangerouslySetInnerHtml { __html STR }: set innerHTML
# - ref|key: see below
DOM EVENTS ==> # - onEvent(REVENT), with REVENT being like EVENT but:
# - better crossbrowser behavior
# - more performant (use only one global event listener, then redistribute)
# - extra properties:
# - nativeEvent EVENT
# - isDefaultPrevented|PropagationStopped(): like jQuery
# - no stopImmediatePropagation()
# - is deleted after function ends, so async can only use it with:
# - copying to local variable
# - or calling REVENT.persist()
FORM CONTROLS ==> #Value:
# - <textarea> children -> <textarea value>
# - <option selected> -> <select value> (STR[_ARR])
# - <input value|checked> -> same
#HTML attributes:
# - onChange:
# - should be used. Like onInput, but with React's behavior for 'value'
# - for checkboxes|radio buttons, do not call REVENT.preventDefault(),
# or control will be updated in model but not in UI
# - value|checked:
# - sets default value
# - makes control read-only: can only updated with new render(), usually
# with this.setState() in onChange event handler
# - not updated on UI interaction but:
# - JavaScript value|checked is
# - if it triggers a new render() with new value|checked, it gets updated like this
# - if null|undefined (as opposed to ''), does not do anything anymore
# - defaultValue|Checked: only sets default value
/=+===============================+=\
/ : : \
)==: JSX :==(
\ :_______________________________: /
\=+===============================+=/
<...> #Like HTML but inside JavaScript:
# - translated as REACT.createElement(...) by transformers (e.g. Babel)
# - e.g. <VAL attr="VAL5" attr2={VAL6}> <hr/> {VAL3} VAL4 </VAL>
# -> REACT.createElement(VAL, { attr: "val5", attr2: val6 }, [ REACT.createElement("hr"), VAL3, "VAL4" ])
# - RTYPE is JavaScript expression (unless HTML tag), i.e.:
# - must be available in scope
# - can be complex, e.g. RTYPE.VAR
# - HTML attribute is stringified, unless {...}
# - boolean attributes must use {BOOL} instead of "BOOL" (def: true)
# - OBJ attributes (e.g. "style"): ATTR="{ ... }" or ATTR={OBJ}
# - can spread an OBJ for several attributes: {...OBJ}
# - children are stringified (i.e. text nodes) unless {...} or <...>
# - JavaScript comments can be used
# - however, where they might be interpreted as text node, must be wrapped in {...}
# - must close tags, including as self-closing tags
TRANSFORMERS ==> ## - Babel plugins (see below)
## - reactify (Browserify)
## - jsx-requirejs-plugin (RequireJS)
@babel/preset-react ##'syntax-jsx', 'transform-react-jsx', 'transform-react-display-name', 'transform-react-jsx-source|self' (in dev)
@babel/syntax-jsx ##
@babel/plugin-transform-react-jsx##Main transformation
@babel/plugin-
transform-react-jsx-self ##Add to props { __self: this }, used for debugging (should be done only in dev)
@babel/plugin-
transform-react-jsx-source ##Add to props { __source: { fileName STR, lineNumber NUM } }, used for debugging (should be done only in dev)
@babel/plugin-transform- ##Move REACT.createElement() that will always return value (e.g. <hr/>) outside of render()
react-constant-elements ##Goal: they are performed only once, i.e. faster reference comparison
##Should not be done in dev, because stack trace harder to read
@babel/plugin-transform- ##Replace REACT.createElement() by faster alternative, but not good for debugging
react-inline-elements ##Should not be done in dev, only production
@babel/plugin-transform-react-jsx-compat
@babel/plugin-transform-react-display-name
AST ==> #See JSX AST doc
/=+===============================+=\
/ : : \
)==: ANIMATIONS :==(
\ :_______________________________: /
\=+===============================+=/
##Package 'react-addons-css-transition-group' (same version as React)
<ReactTransitionGroup> ##RTYPE firing children's RCOMP:
## - componentWillAppear(FUNC()), componentDidAppear():
## - when child is added, on first frame (using ReactTransitionGroup's componentDidMount())
## - componentWillEnter(FUNC()), componentDidEnter():
## - when child is added, on next frames (using ReactTransitionGroup's componentDidUpdate())
## - componentWillLeave(FUNC()), componentDidLeave():
## - when child is removed (using ReactTransitionGroup's componentDidUpdate|Mount())
## - componentDid* wait for componentWill* FUNC to be fired
##Props:
## - component RTYPE|'TAG' (def: 'span'): top-level element
## - other props are passed to props.component
<ReactCSSTransitionGroup> ##<ReactTransitionGroup> firing CSS transitions on children from .appear|enter|leave-CLASS to .appear|enter|leave-CLASS-active
##In details: children componentWillAppear|Enter|Leave():
## - add CSS class 'appear|enter|leave-CLASS'
## - at next tick, add CSS class 'appear|enter|leave-CLASS-active'
## - after timeout, remove both CSS classes.
## Timeout should be same as CSS transition duration.
##Props:
## - transitionAppear|Enter|Leave BOOL (def: false, true, true): enable that feature
## - transitionAppear|Enter|LeaveTimeout NUM (required if switch true)
## - transitionName 'CLASS' or OBJ.appear|enter|leave[Active] 'CLASS'
/=+===============================+=\
/ : : \
)==: PERFORMANCE MEASUREMENT :==(
\ :_______________________________: /
\=+===============================+=/
##Package 'react-addons-perf' (same version as React)
MEASUREMENTS ##Opaque structure
PERF.start|stop() ##Fills in MEASUREMENTS
PERF.isRunning()->BOOL ##
PERF.getLastMeasurements()
->MEASUREMENTS ##
PERF.printInclusive(MEASUREMENTS)##Print time taken by each component, and number of instances.
PERF.printExclusive(MEASUREMENTS)##Same but decompose time from mounting, rendering and the rest.
PERF.printWasted(MEASUREMENTS) ##Same but for the time spent trying to update but giving up because same DOM.
PERF.printOperations(MEASUREMNTS)##Print underlying DOM manipulations.
/=+===============================+=\
/ : : \
)==: IMMUTABLE UPDATE :==(
\ :_______________________________: /
\=+===============================+=/
##Package 'react-addons-update' (same version as React)
UPDATE(OBJ, { VARR: ##Does immutable update (returns without modifying object) (see also immutable-js)
{ $CMD: VAL ... } ... }) ##Possible $CMD:
## - VARR parent must exist:
## - $set VAL: VARR = VAL
## - $apply FUNC(VAL2)->VAL: VARR = FUNC(VARR)
## - VARR must exist and be an OBJ2:
## - $merge OBJ: VARR = _.extend(VARR, OBJ) (shallow merge)
## - VARR must exist and be an ARR:
## - $push|unshift ARR2: VARR.push|unshift(VAL)
## - $splice ARR2_ARR3: VARR.splice(...ARR2), for each ARR2
/=+===============================+=\
/ : : \
)==: TESTING :==(
\ :_______________________________: /
\=+===============================+=/
##Package 'react-dom/test-utils' (same version as React)
TESTUTILS.isElement(RELEM) ##Is RELEM
TESTUTILS.isElementOfType
(RELEM, RTYPE) ##
TESTUTILS.isDOMComponent(RELEM) ##RELEM's RTYPE is RDOM
TESTUTILS.isCompositeComponent
(RELEM) ##RELEM's RTYPE is custom
TESTUTILS.
isCompositeComponentWithType
(RELEM, RTYPE) ##
TESTUTILS.renderIntoDocument ##Like REACTDOM.render(RELEM, ELEM) where ELEM is a detached node.
(RELEM) ##A DOM must still be available (e.g. window.document.createElement())
TESTUTILS.createRenderer() ##Returns RENDERER
RENDERER.render(RELEM[, OBJ]) ##Like REACTDOM.render(RELEM) but:
## - does not require|use a DOM
## - RELEM's children's children are not rendered.
## - REF not supported
##OBJ is context
RENDERED.unmount() ##
RENDERED.getRenderedOutput() ##Returns RCOMP
TESTUTILS.mockComponent
(RTYPE[, 'TAG']) ##Make RCOMP.render() -> <TAG>...</TAG> (def: 'div')
TESTUTILS.findAllInRenderedTree
(RELEM, FUNC(RCOMP)->BOOL) ##Returns RCOMP_ARR
TESTUTILS.scryRenderedDOM
ComponentsWithClass(RCMP,'CLASS')##Same with test for a specific 'CLASS'
TESTUTILS.scryRenderedDOM
ComponentsWithTag(RCOMP, 'TAG') ##
TESTUTILS.scryRenderedDOM
ComponentsWithType(RCOMP, RTYPE) ##
TESTUTILS.find*() ##Like TESTUTILS.scry*(), but returns the first result only, or throw exception if nothing found.
TESTUTILS.Simulate.EVENT ##Trigger EVENT, but still work with virtual DOM and REVENT
(RCOMP|ELEM[, OBJ]) ##OBJ are assigned to EVENT
/=+===============================+=\
/ : : \
)==: LINTING :==(
\ :_______________________________: /
\=+===============================+=/
react/* ##Node module "eslint-plugin-react" (7.28.0)
##Can use CONF.settings.react:
## - createClass 'FUNC' (def: 'createReactClass'): used to create RTYPE
## when not using ES6 classes
## - version STR|'detect' (def: latest)
## - linkComponents 'RTYPE'_ARR or OBJ: name 'RTYPE', linkAttribute STR (def: 'href')
## - RTYPE used instead of <a>
## - for rules like react/jsx-no-target-blank
## - componentWrapperFunctions 'PROP' or OBJ: property 'PROP', object 'VAR'
## - function wrapper components
react/prefer-es6-class [STR] ##Requires either ES6 classes, or ES5 createReactClass()
##STR: 'always' (def), 'never'
react/function-component- ##Whether functional components should use OBJ.[un]namedComponents STR[_ARR] of:
definition [OBJ] ## - 'function-declaration' (def for namedComponents)
## - 'function-expression' (def for unnamedComponents)
## - 'arrow-function'
react/no-this-in-fsc ##No "this" in stateless component
react/no-multi-comp [OBJ] ##Avoid multiple RTYPE declarations per file
##OBJ:
## - ignoreStateless BOOL (def: false): allow if stateless components
react/forbid-elements [OBJ] ##Avoid using <RTYPE>, using OBJ.forbid OBJ_ARR: element 'RTYPE', message STR (error message),
##or shorthand 'RTYPE'_ARR
react/ ##Avoid initializing RELEM inside another one since it loses state and is less performant.
no-unstable-nested-components ##Unless memoized with React.useCallback()
[OBJ] ##OBJ:
## - allowAsProps BOOL: if false (def), also disallow inside props, unless prop name starts with render*
react/react-in-jsx-scope ##React variable must be defined if there is some JSX
react/require-render-return ##Must return a value in render()
react/forbid-component- ##Avoid passing OBJ.forbid VAL_ARR (def: 'className', 'style') as props (except to HTML tags)
props [OBJ] ##VAL can be STR or OBJ: propName STR, allowedFor 'RTYPE'_ARR, message STR
react/forbid-dom-props [OBJ] ##Same for HTML tags
react/style-prop-object [OBJ] ##PROP 'style' must be an OBJ
##OBJ:
## - allow 'RTYPE'_ARR
react/void-dom-elements-
no-children ##Prevent RDOM with no child (like <hr/>) from having children
react/no-namespace ##No HTML namespace (like "svg:*") in RDOM name
react/no-children-prop [OBJ] ##Avoid passing children as props
##OBJ:
## - allowFunctions BOOL (def: false): allow passing FUNC()->children
react/no-redundant-should-
component-update ##Avoid using both shouldComponentUpdate() and PureComponent
react/no-unused-class-
component-methods ##Avoid unused component methods (i.e. dead code)
react/no-arrow-function-lifecycle##Component methods should not use arrow functions
react/destructuring-assignment ##Requires or forbids destructuring of props|state|context
[STR] ##STR: 'always' (def), 'never'
react/no-unknown-property [OBJ] ##Avoid unknown HTML attributes in RDOM
##Can whitelist with OBJ.ignore 'ATTR'_ARR
react/button-has-type [OBJ] ##Enforce that type value of <button> is specified and is valid
##Can pass OBJ.button|submit|reset false to forbid some types
react/no-adjacent-inline-elements##Must separate inline HTML tags (like <a>) with whitespaces.
##Otherwise they would be displayed next to each other with no space in-between.
react/no-unescaped-entities [OBJ]##Must HTML escape > " ' } inside text nodes
##OBJ:
## - forbid STR_ARR (def: > " ' }) or OBJ_ARR: char STR, alternatives STR_ARR (what to replace with)
react/jsx-no-comment-textnodes ##Avoid injecting JavaScript comments as text nodes
react/no-typos ##Avoid case typos on React methods
react/no-deprecated ##Avoid deprecated React methods
react/no-string-refs [OBJ] ##Avoid ref="REF", prefer ref={FUNC(REF)}
##OBJ:
## - noTemplateLiterals BOOL (def: false): no ref={`...`}
react/no-render-return-value ##Avoid assigning ReactDOM.render() return value
react/no-find-dom-node ##Avoid findDOMNode()
react/no-is-mounted ##Avoid isMounted()
react/no-danger ##Avoid dangerouslySetInnerHTML
react/no-danger-with-children ##Avoid using both dangerouslySetInnerHTML and children at the same time
react/no-unsafe ##Avoid UNSAFE_* methods
react/no-invalid-html-attribute
[STR_ARR] ##Avoid specific HTML 'ATTR'_ARR (def: ['rel'])
react/jsx-no-target-blank [OBJ] ##<a target="_blank"> must be accompanied by rel="noreferrer noopener"
##OBJ:
## - enforceDynamicLinks 'always' (def) or 'never': whether to enforce it when URI is JSX
## - allowReferrer BOOL: if false (def), requires noreferrer
## - warnOnSpreadAttributes BOOL (def: false): checks {...OBJ}
## - links|forms BOOL (def: true|false): forbid inside links|forms
react/jsx-no-script-url [OBJ_ARR]##No "javascript:*" URLs
##OBJ_ARR:
## - name 'TAG': only for <TAG>
## - props 'ATTR'_ARR: only for ATTR="..."
react/jsx-key [OBJ] ##Must use "key" when needed
##OBJ:
## - checkFragmentShorhand BOOL (def: false): checks <>...</>
## - checkKeyMustBeforeSpread BOOL (def: false): forbid "key" after {...OBJ}
react/no-array-index-key ##Avoid using an ARR index as "key", e.g. ARR.map((VAL, index) => <RTYPE key={index}>)
react/display-name [OBJ] ##Must specify displayName
##If OBJ.ignoreTranspilerName BOOL false (def), ignore if Babel will fix displayName
react/require-optimization [OBJ] ##Must use shouldComponentUpdate()
##OBJ: allowDecorators 'FUNC'_ARR: ignore if using @FUNC decorators
react/static-property-placement ##How to define static properties ([child]contextType[s], defaultProps, propTypes, displayName):
[STR] [OBJ] ## - 'static public field' (def): class { static VAR = VAL }
## - 'static getter': class { static get VAR(){} }
## - 'property assignment': CLASS.VAR = VAL
##OBJ:
## - VAR STR: same for each static property (e.g. 'defautProps')
react/prop-types [OBJ] ##Must use propTypes
##OBJ:
## - skipUndeclared BOOL (def: false): ignore if there is no propTypes block
## - ignore 'PROP'_ARR
## - customValidators FUNC_ARR: custom ignore
react/require-default-props [OBJ]##Must use defaultProps for every non-required propType
##OBJ:
## - forbidDefaultForRequired BOOL (def: false): must not use defaultProps for a required
## propType
## - ignoreFunctionalComponents BOOL (def: false): ignored for functional components
react/default-props-match- ##Avoid defaultProps with no propType
prop-types [OBJ] ##Also avoid if there is a propType but it is required, if OBJ.allowRequiredDefaults false (def)
react/no-unused-prop-types [OBJ] ##Avoid unused propTypes
##OBJ:
## - skipShapeProps BOOL (def: false): ignore PropTypes.shape
## - ignore 'PROP'_ARR
## - propWrapperFunctions FUNC_ARR:
## - ignore FUNC(PropTypes)
## - FUNC can be 'FUNC' or { property 'FUNC' [, object 'VAR'] }
## - customValidators FUNC_ARR: custom ignore
react/forbid-prop-types [OBJ] ##Avoid using propTypes among OBJ.forbid STR_ARR (def: 'any', 'array', 'object')
##OBJ:
## - check[Child]ContextTypes BOOL (def: false): also check [child]ContextTypes
react/forbid-foreign-prop-types ##When importing propTypes, must do it as:
[OBJ] ## import Component, { propTypes [as ...] } from 'MDL'
##OBJ:
## - allowInPropTypes BOOL (def: false): allow if using from another component
react/prefer-exact-props ##Must use module 'prop-types-exact'
react/sort-comp [OBJ] ##Enforce RTYPE properties sorting order
##OBJ:
## - order 'GROUP'_ARR (order between group), among (following is default order):
## - 'static-methods'
## - 'lifecycle'
## - 'everything-else'
## - 'render'
## (not specified in default order)
## - 'getters', 'setters'
## - 'type-annotations'
## - 'instance-variables'
## - 'instance-methods'
## - 'static-variables'
## - groups.GROUP 'NAME'_ARR (order inside each group), with default for lifecyle:
## 'displayName', 'propTypes', 'contextTypes', 'childContextTypes', 'mixins',
## 'statics', 'defaultProps', 'constructor', 'getDefaultProps', 'state', 'getInitialState',
## 'getChildContext', 'getDerivedStateFromProps', '[UNSAFE_]componentWillMount', 'componentDidMount',
## '[UNSAFE_]componentWillReceiveProps', 'shouldComponentUpdate', '[UNSAFE_]componentWillUpdate',
## 'getSnapshotBeforeUpdate', 'componentDidUpdate', 'componentDidCatch', 'componentWillUnmount'
##Both 'GROUP' and 'NAME' can be REGEXP
react/sort-prop-types [OBJ] ##Enforce propTypes alphabetical sorting
##OBJ:
## - ignoreCase BOOL
## - callbacksLast BOOL (def: false): put on* last
## - requiredFirst BOOL (def: false): put required first
## - sortShapeProp BOOL (def: false): also apply sorting on PropTypes.shape() properties
react/
jsx-no-constructed-context-values##Do not allow OBJ as "value" for contexts
react/no-direct-mutation-state ##Avoid this.state assignments (prefer setState())
react/no-set-state ##Avoid setState()
react/no-did-mount|update-set-
state [STR] ##
react/no-will-update-set- ##Avoid setState() inside componentDidMount|DidUpdate|WillUpdate()
state [STR] ##If STR 'disallow-in-func', also check callbacks inside component*()
react/no-access-state-in-setstate##Avoid setState({ value: this.state.* }). Prefer setState(state => ({ value: state.* }))
react/prefer-stateless- ##Must use stateless components if there is no state
function [OBJ] ##OBJ: ignorePureComponents BOOL (def: false): ignore if child of PureComponent
##and use this.props|context
react/no-unused-state ##Avoid setting state, e.g. with getInitialState(), setState(), etc., that is unused
react/state-in-constructor [STR] ##Whether should RTYPE state should be initialized:
## - 'always' (def): in constructor, as `this.state = OBJ`
## - 'never': as static CLASS property, class { state = OBJ }
react/jsx-no-undef [OBJ] ##Like no-undef RULE, but for JSX
##OBJ: allowGlobals BOOL (def: false)
react/jsx-uses-react ##Fix RULE 'no-unused-vars' for JSX, for React variable
react/jsx-uses-vars ##Fix RULE 'no-unused-vars' for JSX, for RTYPE variables
@stylistic/jsx/ ##Indentation: NUM or 'tab'
jsx-indent [VAL] [OBJ] ##OBJ:
## - checkAttributes BOOL (def: false)
## - indentLogicalExpressions BOOL (def: false): && ||
@stylistic/jsx/ ##Indentation for PROPs
jsx-indent-props [OBJ|VAL] ##OBJ:
## - indentMode NUM, 'tab' or 'first'
## - ignoreTernaryOperator BOOL (def: false)
##VAL is like { indentMode: VAL }
@stylistic/jsx/
jsx-equals-spacing [STR] ##Requires ('always') or forbids ('never', def) spaces around =
@stylistic/jsx/ ##Spaces inside {}
jsx-curly-spacing [OBJ|STR] ##OBJ:
## - when STR: 'always' or 'never' (def)
## - allowMultiline BOOL (def: true)
## - children|expressions STR|BOOL|OBJ: same but distinguish between
## children and non-children
## - spacing: objectLiterals 'always' or 'never': when EXPR is OBJ, i.e. {{}}
##STR is shorthand
@stylistic/jsx/ ##Newlines around {}
jsx-curly-newline [OBJ|STR] ##STR: 'consistent' (def), 'require', 'forbid'
##OBJ:
## - multiline|singleline 'consistent' (def), 'require', 'forbid'
@stylistic/jsx/jsx-newline [OBJ] ##Newlines after <RTYPE> and {...}
##OBJ:
## - prevent BOOL (def: false): if true, not if adjacent
@stylistic/jsx/ ##Spaces around < and >
jsx-tag-spacing [OBJ] ##OBJ:
## - closingSlash STR:
## - 'never' (def): <RTYPE/>, <RTYPE></RTYPE>
## - 'always': <RTYPE/ >, <RTYPE>< /RTYPE>
## - 'allow': ignore
## - beforeSelfClosing STR:
## - 'always' (def): <RTYPE />
## - 'never': <RTYPE/>
## - 'allow': ignore
## - beforeClosing STR:
## - 'always': <RTYPE ></RTYPE >
## - 'never': <RTYPE></RTYPE>
## - 'allow' (def): ignore
## - afterOpening STR:
## - 'never' (def): <RTYPE/>, <RTYPE></RTYPE>
## - 'always': < RTYPE/>, < RTYPE></RTYPE>
## - 'always-multiline': 'never' if no newline after <, 'allow' otherwise
## - 'allow': ignore
@stylistic/jsx/
jsx-props-no-multi-spaces ##Avoid multiple consecutive spaces inside <...>
@stylistic/jsx/ ##Inline HTML tag should not be on their own line, or whitespaces will collapase
jsx-child-element-spacing ##E.g. <p>Here is\n<a>test</a></p> becomes <p>Here is<a>test</a></p>
@stylistic/jsx/ ##Where to put /> or </
jsx-closing-bracket-location ##OBJ:
[STR|OBJ] ## - selfClosing (only for self-closing tags) STR:
## - 'tag-aligned': vertically aligned with <
## - 'line-aligned': next line
## - 'after-props': no new line if self-closing, next line otherwise
## - 'props-aligned': aligned with props if self-closing, next line otherwise
## - nonEmpty (inverse)
##STR is shorthand for both
@stylistic/jsx/
jsx-closing-tag-location ##Closing tag must be on same line as opening tag, or vertically aligned with it
@stylistic/jsx/ ##Newline before first PROP, among:
jsx-first-prop-new-line [STR] ## - 'never'
## - 'always'
## - 'multiline': if JSX is multiline
## - 'multiline-multiprop': if JSX is multiline and has several PROPs
@stylistic/jsx/ ##Newline before|after JSX when used as FUNC() argument
jsx-function-call-newline [STR] ##STR:
## - 'always'
## - 'multiline' (def): if JSX is multiline
@stylistic/jsx/ ##Requires wrapping multiline JSX in ()
jsx-wrap-multilines [OBJ] ##Can restrict to specific TYPEs, using OBJ:
## - declaration|assignment|return|arrow STR (def: 'parens')
## - condition|logical|prop|propertyValue STR (def: 'ignore')
##STR can be:
## - 'ignore'
## - 'parens'
## - 'parens-new-line': also require newlines around ( )
@stylistic/jsx/ ##Avoid two <RTYPE> on same line
jsx-one-expression-per-line ##OBJ:
[OBJ] ## - allow STR (def: "none"): allow <RTYPE>...</RTYPE> when ... is "literal", "single-child", "single-line" or "non-jsx"
@stylistic/jsx/ ##Must use <RTYPE /> if there is no child
self-closing-comp [OBJ] ##For OBJ: component|html BOOL (def: true, false) (non-RDOM, RDOM)
react/jsx-no-duplicate-props ##Prevents duplicate PROPs
[OBJ] ##OBJ: ignoreCase BOOL (def: false)
@stylistic/jsx/ ##Max PROPs per line
jsx-max-props-per-line [OBJ] ##OBJ:
## - maximum NUM (def: 1)
## - single|multi NUM: same but only inside single|multiple line elements
## - when STR: 'always' (def) or 'multiline' (only checks if multiline JSX)
react/jsx-props-no-spreading ##Forbids <RTYPE {...PROPS}>
[OBJ] ##OBJ:
## - custom|html 'enforce' (def) or 'ignore': for [non-]RDOM
## - explicitSpread 'enforce' (def) or 'ignore': if 'ignore', allow if PROPS is a literal OBJ
## - exceptions 'RTYPE'_ARR
react/jsx-max-depth [OBJ] ##Max nesting OBJ.max NUM (def: 2)
@stylistic/jsx/ ##Requires <RType> to be PascalCase
jsx-pascal-case [OBJ] ##OBJ:
## - allowAllCaps BOOL (def: false)
## - allowLeadingUnderscore BOOL (def: false)
## - allowAllNamespace BOOL (def: false): if true, only in 'VAR' if 'VAR.VAR2'
## - ignore 'RTYPE_GLOB'_ARR: whitelists
react/boolean-prop-naming [OBJ] ##Requires PROPs with propTypes.VAR (OBJ.propTypeNames "VAR"_ARR, def "bool") names to
##match OBJ.rule REGEXP (def: "^(is|has)[A-Z]([A-Za-z0-9]?)+")
##OBJ:
## - message STR: can use '{{propName}}' and '{{pattern}}'
## - validateNested BOOL (def: false)
react/jsx-handler-names [OBJ] ##Requires PROPs naming for:
## - event handlers PROP: start with OBJ.eventHandlerPropPrefix STR|BOOL (def: 'on')
## - event handlers PROP's value: start with OBJ.eventHandlerPrefix STR|BOOL (def: 'handle')
##E.g. onChange={this.handleChange}
##OBJ:
## - checkLocalVariables BOOL (def: false): check event handlers stored as local variables too
## - checkInlineFunctions BOOL (def: false): check event handlers stored as inline functions too
@stylistic/jsx/jsx-sort-props ##Requires sorting PROPs
##OBJ:
## - noSortAlphabetically BOOL (def: false)
## - ignoreCase BOOL (def: false)
## - callbacksLast BOOL (def: false): on* must be last
## - shorthandFirst|Last BOOL (def: false): boolean attribute must be first|last
## - reservedFirst STR_ARR|BOOL (def: 'children', 'dangerouslySetInnerHTML', 'key', 'ref'):
## must be first
## - multiline 'first', 'last', 'ignore' (def)
## - locale 'auto' (def) or 'LOCALE'
react/jsx-sort-default-props ##Requires sorting defaultProps
##OBJ:
## - ignoreCase BOOL (def: false)
@stylistic/js/jsx-quotes [STR] #Whether using ATTR="" or ATTR='' in JSX
#STR: 'prefer-double' (def), 'prefer-single'
react/jsx-boolean-value [STR] ##Whether BOOL attributes should be ATTR ('never', def) or ATTR={BOOL} ('always')
[OBJ] ##OBJ: always|never "ATTR"_ARR (exceptions)
react/jsx-no-bind [OBJ] ##Avoid, according to OBJ:
## - allowFunctions false (def): PROP value being a non-arrow function
## - allowArrowFunctions false (def): PROP value being an arrow function
## - allowBind false (def): PROP value being a FUNC.bind()
##Can whitelist with:
## - OBJ.ignoreRefs true (def: false): for ref={FUNC}
## - OBJ.ignoreDOMComponents true (def: false): for onDOMEVENT
react/jsx-no-literals [OBJ] ##Requires <...>{'STR'}</...> instead of <...>STR</...>
##OBJ:
## - noStrings BOOL (def: false): forbids any literal STR in JSX, even outside {}
## - noAttributeStrings BOOL (def: false): forbids any literal STR in attributes
## - allowedStrings STR_ARR
## - ignoreProps BOOL (def: false): ignore inside props
@stylistic/jsx/ ##Whether {} should be required ("always"), never allowed unless necessary ("never") or "ignore"
jsx-curly-brace-presence [OBJ] ##Using OBJ: props STR, children STR
react/jsx-fragments [STR] ##Require JSX fragments to be:
## - 'syntax': <>...</> (except if using 'key' JSX attribute)
## - 'element': <React.Fragment>...</React.Fragment>
react/jsx-no-useless-fragments ##Avoid <>...</> if either it:
[OBJ] ## - has only one child
## - is the child of a RDOM
##OBJ:
## - allowExpressions BOOL (def: false): allow single EXPR
react/jsx-filename-extension ##Requires files containing JSX to have OBJ.extensions '.EXT'_ARR (def: '.jsx')
[OBJ] ##OBJ:
## - allow 'always' (def) or 'as-needed': whether to forbid files not containing JSX to have OBJ.extensions
react/prefer-read-only-props ##Enforce read-only types with Flow for props
/=+===============================+=\
/ : : \
)==: TYPESCRIPT :==(
\ :_______________________________: /
\=+===============================+=/
tsc --jsx STR #Allows JSX.
#Must also use *.tsx instead of *.ts
#It is type checked.
#It is also transpiled according to STR:
# - 'preserve' (def): kept as is, with *.jsx
# - 'react-native' (def): kept as is, with *.js
# - 'react[-native]': to React.createElement(...), with *.js
# - 'react-jsx': to jsx()
# - 'react-jsxdev': to jsxs()
#Cannot use <TYPE>VAL (but can use "VAL as TYPE")
tsc --jsxFactory STR #'FUNC' (def: 'React.createElement') used with --jsx 'react'
/* @jsx STR */ #Useful when using an alternative library (e.g. Preact)
tsc --jsxFragmentFactory STR
/* @jsxFrag STR */ #'FUNC' (def: 'React.Fragment') used with --jsx 'react'
tsc --jsxImportSource MODULE
/*jsxImportSource MODULE #MODULE to use (def: 'preact/jsx-runtime')
TYPES ==> #
React #NAMESPACE
JSX #NAMESPACE
JSX.Element #TYPE of RELEM
JSX.ElementClass #TYPE of CLASS RTYPE
JSX.IntrisicElements #INTERFACE { 'TAG': { 'ATTR': TYPE }, ... } with all possible RDOMs and their ATTRs.
#Can merge to it to add new ones.
JSX.ElementAttributesProperty #INTERFACE { 'PROP': {}, ... } specifying which RTYPE[PROP] should be used to retrieve PROPs TYPEs
#Default to 'props'
JSX.IntrinsicAttributes #INTERFACE { 'PROP': TYPE, ... } of PROPs shared by all RELEMs (e.g. 'key')
JSX.IntrinsicClassAttributes<CLAS>#Same only for CLASS RELEMs (e.g. 'ref')
JSX.ElementChildrenProperty #Same as JSX.ElementAttributesProperty but for RCHILDREN TYPEs