-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreact_notes.txt
More file actions
1610 lines (1326 loc) · 79 KB
/
Copy pathreact_notes.txt
File metadata and controls
1610 lines (1326 loc) · 79 KB
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
997
998
999
1000
- REACT NOTES -
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
GENERAL NOTES:
-React is a JS library for building UI's
-Created by Facebook
-Can be used to create single page apps, "SPA's"
-eliminate page loading
-faster more responsive feeling app
-Can be used with any technology
-Does not disable standard JS DOM manipulation
-Incredibly popular
-Uses components to build the DOM
-React Component is simply defined by a function that returns a React Element
-can be a functional component
-function that returns React Element
-or class component
-class that returns React Element
-maybe one component for a form, one for a navbar etc...
-components are capitalized by convention
-Can be used within an .html doc if the scripts are linked
*************************************************************************************************
<script crossorigin="" src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin="" src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
*************************************************************************************************
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE REACT APP:
- "create-react-app"
-starter-kit that uses "Webpack" under the hood
-Webpack is a popular "bundler"
-bundlers are used by most modern JS projects to "build" the source code into production-ready files
-Allows apps to be broken down into smaller modules and transformed based on tools called "loaders"
1. run " npx create-react-app [+project_name] "
-"npx" is a tool that comes with npm v5.2 and higher
-will create new React project folder in the directory that it is run from
2. navigate to the newly-created project folder
3. run "npm start"
-runs React development server and opens a browser tab that navigates to the default app
-server has live reload feature that reloads app whenever code changes are saved
4. overview of how the app is structured and modules communicate:
*************************************************************************************************
-i.e. *PUBLIC/INDEX.HTML*
<-- holds the main page that reacts -->
<html>
<head>
</head>
<body>
<div id='root'></div>
</body>
</html
*SRC/APP.JS*
// holds all the other components that may contain nested components themselves
function App(){
return(
<div className="App">
//Other components live here
</div>
)
}
*SRC/INDEX.JS*
// creates main <App/> Component in "index.html" within the "root" element
ReactDOM.render(<App/>, document.getElementById('root'));
(^ demonstrates the .render() method calling the <App/> component on the "root" element ^)
*************************************************************************************************
5. default App code can be mostly deleted!
*************************************************************************************************
-i.e. *SRC/APP.JS"
// the React import allows the writing of JSX in this .js file
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
(^ everything between the return parentheses can be deleted, and all imports but React!^)
*************************************************************************************************
6. create "components" directory within the "src" directory
-this is where all the components for the React project will go!
-to be imported and used by Apps
-capitalize all components!
-React offers plenty of freedom over folder structuring for React projects
-React is just a library and very unopinionated
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
USING JSX:
-JSX is a JS syntax extension that allows the interpretation of normal HTML syntax by JS without having to make it a string
*************************************************************************************************
-i.e. class App extends Component {
render() {
return (
<h1>Hello World</h1>
);
}
}
(^ basic JSX used to create a component "App" with a .render() method returning an <h1> HTML tag ^)
*************************************************************************************************
-JSX has some limitations
-JSX expressions can only have one Parent Element
-must "break-free" from JSX syntax with "{}" curly-braces when need to insert JS
-traditional "if-statement" syntax IS NOT supported this way though!
-Ternaries are fine and so are "switch/case" conditionals
-alternative "if-statement" syntax available though
*************************************************************************************************
-i.e. // would throw an error that "JSX elements must be wrapped in an enclosing tag"
class App extends Component {
render(){
return (
<h1>Hello World</h1>
<p>This is a paragraph</p>
);
}
}
// you can enclose them within a single tag like <div> or use a JSX "Fragment" like below
class App extends Component {
render(){
return (
<>
<h1>Hello World</h1>
<p>This is a paragraph</p>
</>
);
}
}
// alt "if-statement" syntax creates different <p>'s depending on the value of "props.cat"
return (
<div>
<h1>{responseData.name}</h1>
{props.cat === 'people' &&
<>
<p>Height: {responseData.height}</p>
<p>Mass: {responseData.mass}</p>
<p>Hair Color: {responseData.hair_color}</p>
<p>Skin Color: {responseData.skin_color}</p>
</>
}
{props.cat === 'planets' &&
<>
<p>Climate: {responseData.climate}</p>
<p>Terrain: {responseData.terrain}</p>
<p>Surface Water: {responseData.surface_water}</p>
<p>Population: {responseData.population}</p>
</>
}
</div>
);
(^ demonstrates some changes to JS when used within JSX ^)
*************************************************************************************************
-Not totally the same syntax as HTML either
-i.e. "className" must be used instead of "class" for JSX elements
-b/c JS already has a "class" keyword reserved!
-i.e. "htmlFor" must be used instead of "for" for JSX forms
-same reason, "for" is already reserved by JS!
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATING FUNCTIONAL COMPONENTS:
-"creating class components" below:
1. "React.createElement()"
-React method that creates a basic component
*************************************************************************************************
-i.e. // creates a basic h1 element
const myReactComponent = React.createElement("h1", {}, "I am creating my first React component")
// creates a nested React Component
const myNestedReactComponent = React.createElement("div", {}, React.createElement("p", {}, "This element is nested"))
(^ demonstrates basic syntax of React.createElement() ^)
*************************************************************************************************
-has 3 main parameters
1. what kind of element to create
-like an <h1>
2. props object
-empty object passed to every react component by default
-short for "properties"
3. children to include
-what to go inside the element tags
-can be string like "I am creating my first React component"
-or another component nested with another React.createElement
-like more nested .html elements
-elements must still be rendered before they will show on the browser!
2. "ReactDOM.render()"
-tells React to display a component
-takes 2 arguments
1. the component to display
2. the element to display it within
-overwrite whatever is in the targetted parent component?
*************************************************************************************************
-i.e. // creates a component
const App = React.createElement("h1", {}, "Our First React page has rendered");
// renders the component stored in the variable
ReactDOM.render(App, document.getElementById("root"));
// creates an arrow-function method "App()" to create components
const App = () => React.createElement("h1", {}, "Our First React page has rendered");
// renders the component created by the method
ReactDOM.render(App, document.getElementById("root"));
(^ demonstrates how to create and render components w/methods and variables ^)
*************************************************************************************************
3. Babel
-Transpiler that allows the use of JSX (JavaScript Syntax Extension) language within <script> tags on HTML page
-not allowed out of the box
-the JSX would be interpreted as miswritten JS!
-NOT needed when React is being coded from within a React file instead of an HTML
-because "import React from 'react'" will be used to allow it
-Added to a page with a script tag
- "<script type="text/babel"></script>"
-Just syntactic sugar to allow the use of regular HTML syntax for convenience
*************************************************************************************************
-i.e. // indicates Babel is to be used
<script type="text/babel">
// JSX can be rendered directly without using a component if Babel is in use
ReactDOM.render(<h1>Hello!</h1>, document.getElementById("root"));
// **Here is what the Babel translation looks like**
ReactDOM.render(React.createElement("h1", null, "Hello World"), document.getElementById("root"));
// using Babel to make a method for component creation
const App = () => <h1>Our First React page has rendered</h1>;
// we wrap our function name in an HTML tag instead of adding "()" to the end like JS
ReactDOM.render(<App></App>, document.getElementById("root"));
// Babel allows self closing JSX tags as well, like below
ReactDOM.render(<App />, document.getElementById("root"));
(^ demonstrates basic use of Babel transpiler ^)
*************************************************************************************************
-can tell the difference between React Component and normal HTML element b/c Components are capitalized
-React treats lowercase tags as HTML tags!
4. JSX:
-Can be used to create and render elements without the use of .createElement()
-Looks like direct HTML but with some subtle differences
*************************************************************************************************
-i.e. *PERSONCARD.JS*
// creates PersonCard component that takes props from App as args
import React from 'react';
const PersonCard = props => {
return(
<div>
<h1>{ props.lastName }, { props.firstName }</h1>
<p>Age: { props.age }</p>
<p>Hair Color: { props.hairColor }</p>
</div>
);
}
export default PersonCard;
*APP.JS*
...
<PersonCard firstName="John" lastName="Smith" age={ 8 } hairColor="Brown" />
(^ shows basic functional component being passed props as args from its App call ^)
*************************************************************************************************
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
CLASS-COMPONENTS:
-ES6 Class can be used to create React Elements instead of a function
-Basic steps to creating and using class-components:
1. make sure there is a 'components' directory created within 'src' directory found in project's root
2. create .js file in 'components' directory
-this is the component file
3. import default Component class from React
-i.e. " import React, { Component } from 'react'; "
4. code the component and export it!
-follow the rules below to code it
-MUST end with an export!
-i.e. " export default [+Component_name] "
5. import the comonent with the Apps that will use it
-i.e. " import [+Component_name] from './components/[+Component_name]'; "
6. now it can be used in the Apps!
-XML example:
-i.e. " <[+Component_name]/> "
-There are 3 requirements for a Class Component to be valid
1. class names must start with a capital letter
2. class must extend React.Component
-i.e. "class [+Class_name] extends React.Component {}"
3. class must have a render() method that returns a React Element either by JSX or React.createElement()
-must produce something!
*************************************************************************************************
-i.e. import React, { Component } from 'react';
class SomeClassComponent extends Component {
render() {
return <div>This is our first class component.</div>;
}
}
export default SomeClassComponent;
(^ basic Class Component ^)
*************************************************************************************************
- "this.props" accesses props in a class-component
-already have access to the props variable defined by the Component class since it's being extended
-The class props can also be destructured like this:
*************************************************************************************************
-i.e. // uses this.props to access props for the component
class Header extends React.Component {
render() {
return (
<div>
// By inheriting from React.Component all we need is the "this" keyword in front of props.
<h1>My name is { this.props.firstName } { this.props.lastName }</h1>
</div>
);
}
}
// creates firstName and lastName variables to hold references to the props via destructuring
class Header extends React.Component {
render() {
const { firstName, lastName } = this.props;
return (
<div>
// Destructuring allows us to use them like variables. This is just a small amount of syntactical sugar.
<h1>My name is { firstName} { lastName }</h1>
</div>
);
}
}
(^ shows how props can be accessed traditionally or via destructuring ^)
*************************************************************************************************
-Props variable is useful for passing data down from component to component
-can pass data up too?
-no limit to amount that can be passed-down via props
-anything can be passed down
-strings are allowed by default, but anything else needs curly-braces "{}" around it
-numbers
-objects / arrays
-functions can even be passed down!
-strings work in braces too!
-when in doubt, just use curly-braces!
*************************************************************************************************
-i.e. // Valid. We can send normal strings, but in numbers need curly braces
<SomeComponent someProp="test" someOtherProp={ 67 }/>
//Valid. A String is still a Javascript expression
<SomeComponent someProp={ "test" } someOtherProp={ 67 }/>
//Invalid. Numbers need curly braces
<SomeComponent someProp="test" someOtherProp=67/>
(^ shows how to pass-down various data types by creating props to access with components ^)
*************************************************************************************************
-Children of a component can also be accessed by the component via props
-i.e. " this.props.children "
*************************************************************************************************
-i.e. *APP.JS*
// calls component with a header prop and 3 <p> children
import React from 'react';
import './App.css';
import MyNewComponent from './components/MyNewComponent';
function App() {
return (
<div className="App">
<MyNewComponent header={ "Header Prop" }>
<p>This is a child</p>
<p>This is another child</p>
<p>This is even another child</p>
</MyNewComponent>
</div>
);
}
export default App;
*MYNEWCOMPONENT.JS*
// uses the header prop to render a <h1> and all children of the component
import React, { Component } from 'react';
class MyNewComponent extends Component{
render(){
return(
<div>
<h1>
{ this.props.header }
</h1>
{ this.props.children }
</div>
);
}
}
export default MyNewComponent;
(^ shows how to access a component's children ^)
*************************************************************************************************
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
CLASS-COMPONENTS VS. FUNCTIONAL-COMPONENTS:
-Components can be built as either classes or functions
-Class-componenets used to be the way to go
-used to be more robust
-had state handling ability where functional-components did not
-The creation of "hooks" allows functional-components to access state!
-NO hook can ever be called conditionally
-makes functional-components more useful most of the times
-most new React code will use functional-components
-React team stated that they will still support clas-components though
-can be mixed and matched
-many old apps still use class-components
-functional components should be preffered and used
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
PRESENTATIONAL AND CONTAINER COMPONENTS:
-Design paradigm wherein there are generally two types of components:
1. One that presents information that is passed down to it
2. Another that does the logic and work to actually get that data
-Some components are just accepting props and performing actions based on those props. Others are "doing the work".
-i.e. A Main component making calls to an API to retrieve People, and any other logic required. A PersonList component is simply accepting data and callbacks and props.
-By adhering to this philosophy, it can be quite easy to re-use components, b/c we can create a generic component, such as a button, that will do something when you click it
-the button component can be completely agnostic as to what this action is, it will simply just execute whatever method you pass down.
-if we design a button like this, then we can easily reuse it for anytime we want to execute a function when clicking on a button, instead of writing many different buttons that do different things
-While it can be useful, you should not try to force this design pattern.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
SYNTHETIC EVENTS:
-React uses a custom approach to add event listeners to our elements
-wraps the browser's native elements and applies its own event system called "Synthetic Events"
-3 main rules:
1. event names are camelCased instead of lowercase
-i.e "onclick" becomes "onClick"
2. returning false will not work with any event, to prevent bubbling
-you will need to manually "callevent.stopPropagation()" or "e.preventDefault()" as necessary
3. events cannot be called asynchronously because of how React "pools" the Synthetic events
*************************************************************************************************
-i.e. // creates click event that creates alert when a button is clicked
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
// listener expression must be in a function or it will run on load immediately instead of on click
<button onClick={ ()=> alert("This button has been clicked!") }>Click Me</button>
);
}
export default App;
(^ shows basic click event-listener ^)
*************************************************************************************************
-Some other common events:
- "onChange"
-runs when a form input is changed
-i.e. " <input type="text" onChange={ (e) => setUsername(e.target.value) } /> "
-"e.target" is the input that is changed!
- "onSubmit"
-runs when a form is submitted
- "onFocus"
-runs when an element is given focus
-(clicked on or tabbed to)
- "onBlur"
-runs when an element loses focus
-(user clicked or tabbed away)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
STATE:
1.Class-Components:
-Components can store their own data instead of just having it given to them through props
-"State" is what we will call the variable that a Component will hold their own data with
-like a light-switch, either in "on" or "off" state that persists until changed
-State will be made an attribute of the class
-class needs a constructor to give attributes
-state attribute must hold an object
-object will hold the state keys
-state information will be accessed via the keys of this object
-i.e. " {this.state.position} "
-State can ONLY be altered with ".setState()" method
-because the state is treated as immutable by React
-i.e. " { this.state.position = "Off" } " won't work
-i.e. " { this.setState({ position = "Off" }) } " will work
*************************************************************************************************
-i.e. *APP.JS*
// app calls PersonCard twice
import React from 'react';
import PersonCard from './components/PersonCard';
function App() {
return (
<>
<PersonCard firstName="Jane" lastName="Jane" age={ 45 } hairColor="Black"/>
<PersonCard firstName="John" lastName="Smith" age={ 88 } hairColor="Brown"/>
</>
);
}
export default App;
*PERSONCARD.JS*
import React, { Component } from 'react';
// PersonCard class is created with the state attribute to hold its initial age prop data
class PersonCard extends Component {
constructor(props) {
super(props);
this.state = {
age: this.props.age
};
}
// ageUp method is created to overwrite the state object, effectively updating the age
ageUp = () => {this.setState({age: this.state.age + 1})};
// rendered <button> calls .ageUp() method to change the state and then displays in <p>
render() {
const { firstName, lastName, age, hairColor } = this.props;
return (
<div>
<h1>{lastName}, {firstName}</h1>
<p>Age: {this.state.age}</p>
<p>Hair Color: {hairColor}</p>
<button onClick={this.ageUp}>BirthdayButton for {this.firstName} {this.lastName}</button>
</div>
)
}
}
export default PersonCard;
(^ shows basic implementation and use of state ^)
*************************************************************************************************
2.Functional-Components:
-Didn't use to have state handling abilities
-Can now mimic it with "hooks"
-hooks are now extremely important in React
-allows you to "hook" in or use a certain piece of functionality
-"useState()" is such a hook
-call it and argue the state object to it
-DOES NOT need to argue an obj for state like Class-Components do!
-Can pass primitive values instead, without a value pair
-takes pace of "state" var (see below)
-this is the most common way it's used with functional-components!
-can be done multiple times in each component, effectively creating multiple hooks!
-destructure it into "state" and "setState"
-if passing a primitive, "state" will be replaced with the "key" so to speak of the state value
-the "setState" name changes as well!
-i.e. " const [count, setCount] = useState(0); "
-access the state with "state" and update it with "setState"
*************************************************************************************************
-i.e. // needs the following import to work either way!
import React, { useState } from 'react';
1. // argues the state object with useState to create state, then destructures it into state and setState vars
const Counter = props => {
const [state, setState] = useState({
clickCount: 0
});
// updates state by using setState to determine a new state based off the current state
const handleClick = () => {
setState({
clickCount: state.clickCount + 1
});
}
// returns state info by accessing it via the destructured state var
return(
<div>
{ state.clickCount }
<button onClick={ handleClick }>Click Me</button>
</div>
);
}
2. // argues the state as a single primitive value that is named "count"
const Counter = props => {
const [count, setCount] = useState(0);
// updates
const handleClick = () => {
setCount(count + 1);
}
// returns state info via the destructured "count" variable
return (
<div>
{ count }
<button onClick={ handleClick }>Click Me</button>
</div>
);
}
export default Counter;
(^ shows how hooks are used with obj state vs primitive state ^)
*************************************************************************************************
3. Lifting State Up:
-suppose we want to make an app containing a component for creating messages and a component for displaying them
-solution is that we can provide a prop to the <MessageForm /> from the parent of both it and <MessageDisplay />
-props can be functions!
-if this prop is a function, then we can have the child component call the function!
-if the function accepts a parameter, then the child can pass a parameter into this function!
*************************************************************************************************
-i.e. *APP.JS*
import React, { useState } from 'react';
import MessageForm from './Components/MessageForm';
import MessageDisplay from './Components/MessageDisplay';
function App() {
const [currentMsg, setCurrentMsg] = useState("There are no messages");
// creates a function to update the currentMsg state
const youveGotMail = ( newMessage ) => {
setCurrentMsg( newMessage );
}
return (
<>
// passes the function down to the MessageForm as a prop
<MessageForm onNewMessage={ youveGotMail } />
// passes down the currentMsg data that was lifted from MessageForm as a prop to MessageDisplay
<MessageDisplay message={ currentmsg } />
</>
);
}
*MESSAGEFORM.JS*
import React, { useState } from 'react';
const MessageForm = (props) => {
const [msg, setMsg] = useState("");
// onNewMessage() function in prop is able to pass this component's state data back up!
const handleSubmit = (e) => {
e.preventDefault();
props.onNewMessage( msg );
};
return (
<form onSubmit={ handleSubmit }>
<h1>Set Message</h1>
<textarea
rows="4"
cols="50"
placeholder="Enter your message here"
onChange={ (e) => setMsg(e.target.value }
value={ msg }
></textarea>
<input type="submit" value="Send Message" />
</form>
);
};
export default MessageForm;
*MESSAGEDISPLAY.JS*
import react, { useState } from 'react';
// returns JSX with the message from props
const MessageDisplay = (props) => {
return (
<>
<h1>Current Message</h1>
<pre>{ props.message }</pre>
</>
);
};
export default MessageDisplay;
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
LIFECYCLE METHODS:
-Using class components gives easy access to React's lifecycle methods
-Every component, both class and functional, has a lifecycle it goes through
-from creation/mounting to destruction/unmounting
-the methods used to access these lifecycles are called "lifecycle methods"
-lifecycle methods are automatically called in the background
-Component's lifecycle can be split into 4 stages, each with methods that run in a certain order
1. mounting:
-stage where React creates and inserts component into the DOM
1. constructor()
-state is assigned here
-event handlers are bound here
-React sets default and initial values for the props and the state
-first method called before the component is actually mounted
-NOT where API calls are made or subscriptions introduced
2. render()
-html content is processed and rendered here
3. componentDidMount()
-immediately follows completion of the render methodd
-where we'd initialize network requests, subscriptions, timers
-where we'd target DOM nodes from component tree
2. updating:
-stage that runs every time the component's state or properties
1. shouldComponentUpdate(nextProps, nextState)
-gives ability to explicitly tell React if component should be re-rendered after a change in state or props
-used to optimize performance
-true by default
-can change to false if don't want the component to re-render
3. unmounting:
-final stage where React unmounts the component and removes it from the DOM
1. componentWillUnmount()
-invoked right before the component is unmounted
-ideal place to cancel any on-going network requests, subscriptions, or to clear timers
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
STYLES WITH REACT:
-There are a few ways to add styles to a React App:
1. Direct Import:
-.css file can be imported directly and referenced
-bootstrap works too (see #4 in this section)
-make sure to use "className" instead of "class" to assign JSX element classes
*************************************************************************************************
-i.e. *STYLES.CSS*
.btn {
padding: 12px 15px;
font-family: Arial, sans-serif;
font-weight: bold;
background: linear-gradient(30deg, rebeccapurple, magenta);
color: #fff;
border: none;
}
*MYBUTTONCOMPONENT.JS*
import React, { Component } from 'react';
import './styles.css';
class MyButton extends Component {
render() {
return <button className="btn">{ props.children }</button>;
}
}
export default MyButton;
(^ shows styling by importing a .css file ^)
*************************************************************************************************
2. Inline Styles:
-object variable can be created in the component to work like a CSS ruleset
-then the object is passed to an element under the usual "style" attribute
-just like regular HTML
-CSS MUST be camelCased when used in objects like this
-ALL values in the object's pairs must be enclosed in strings
-does NOT support pseudo-classes!
-does NOT support media queries!
*************************************************************************************************
-i.e. *MYBUTTONCOMPONENT.JS*
import React, { Component } from 'react';
1. // object is created to form a css ruleset...property names must be camelCased with commas seperating them
const btnStyle = {
padding: '12px 15px',
fontFamily: 'Arial, sans-serif',
fontWeight: 'bold',
background: 'linear-gradient(30deg, rebeccapurple, magenta)',
color: '#fff',
border: 'none'
};
// style attribute of element is filled with the css data from the btnStyle object
class MyButton extends Component {
render() {
return <button style={ btnStyle }>{ props.children }</button>;
}
}
2. // css ruleset is created entirely inline within double curly-braces
class MyButton extends Component {
render() {
return <button style={{padding: '12px 15px', fontFamily: 'Arial, sans-serif', etc...}}>{ props.children }</button>;
}
}
export default MyButton;
(^ shows how to use inline-styling ^)
*************************************************************************************************
3. CSS Modules:
-overcomes many problems with the first 2 approaches
-media queries can be used like normal
-BUUUT class names CANNOT be hyphenated!
-so camelCasing is used by convention
-"create-react-app" supports CSS modules by default
-place within components folder with the component it matches
-" <+component_name>.module.css " naming convention
-no matter what it MUST end in ".module.css" !
-components can use different styles of the same name without conflict
-i.e. another component could use another stylesheet with another .btnStyle that has different rules
-the CSS class names are given unique hashes at build time to keep them isolated
*************************************************************************************************
-i.e. *MYBUTTONCOMPONENT.MODULE.CSS*
// CSS class name is camel cased, but properties can be written regularly!
.btnStyle {
padding: 12px 15px;
font-family: Arial, sans-serif;
font-weight: bold;
background: linear-gradient(30deg, rebeccapurple, magenta);
color: #fff;
border: none;
}
*MYBUTTONCOMPONENT.JS*
import React, { Component } from 'react';
// the "." signifies same directory, and the "/" accessess the specified CSS module from there
import styles from './MyButtonComponent.module.css';
class MyButton extends Component {
render() {
return <button className={ styles.btnStyle }>{ props.children }</button>;
}
}
export default MyButton;
(^ shows how CSS modules can be used without special adjustments like the first 2 approaches needed ^)
*************************************************************************************************
4. Bootstrap!
-Regular Bootstrap classess can be used, or "ReactStrap" for premade componenets, like Material UI has
-"ReactStrap" not covered here
- " npm install react-bootstrap bootstrap "
- " import 'bootstrap/dist/css/bootstrap.min.css'; "
-include at top of "App.js" or "index.js" file
-Bootstrap classes can now be added to Apps and Components via className JSX attribute!
*************************************************************************************************
-i.e. //import individual components to reduce data sent to client!
import Button from 'react-bootstrap/Button';
// or less ideally
import { Button } from 'react-bootstrap';
(^ demonstrates basic use of Bootstrap with React ^)
*************************************************************************************************
5. Material UI
-CSS library of pre-made React componenents
-To install:
1. In React client directory:
- " npm install @material-ui/core "
2. Import specific Material-UI componenents as needed in each file
-i.e. " import { Paper } from '@material-ui/core'; "
-Some useful components:
1. Paper and Cards:
-A Paper component is one that will give a nice background and potentially some elevation to a component.
*************************************************************************************************
-i.e. import { Paper } from '@material-ui/core';
...
<Paper elevation={3}>
<p>Some text here</p>
</Paper>
...
(^ demonstrates basic use of a Paper component ^)
*************************************************************************************************
-A Card componenent is one you can give different elevations to make it appear "higher up" on the page.
*************************************************************************************************
-i.e. import { Card } from '@material-ui/core';
...
<Card>
<CardContent>
<h1>This is content within my card</h1>
</CardContent>
</Card>
...
(^ demonstrates basic use of Card components ^)
*************************************************************************************************
2. Buttons
-Material-UI has very nice looking buttons as well. It is as simple as importing it and implementing it:
*************************************************************************************************
-i.e. import { Button } from '@material-ui/core';
...
<Button>
Click Me
</Button>
...
(^ demonstrates basic use of Button componenent ^)
*************************************************************************************************
3. Forms
-Material can make very nice looking forms as well. We can do something simple like:
*************************************************************************************************
-i.e. *components/LoginForm.js*
import React from 'react';
import {
Paper,
FormControl,
InputLabel,
OutlinedInput,
Button
} from '@material-ui/core';
const styles = {
paper: {