└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # React Cheatsheet
2 | Set of basic functionalities from React in one place.
3 |
4 | Cheatsheet has been created by https://foreach.pl trainers for training participants.
5 |
6 | **Check also other Cheatsheets:**
7 |
8 | [Angular](https://github.com/delprzemo/angular-cheatsheet)
9 |
10 | [TypeScript](https://github.com/delprzemo/typescript-cheatsheet)
11 |
12 |
13 | # Table of Contents
14 |
15 |
16 | * [Basic React commands](#Basic-React-commands)
17 | * [JSX](#JSX)
18 | * [Injection JS into HTML](#Injection-JS-into-HTML)
19 | * [Element declaration](#Element-declaration)
20 | * [Function injection](#Function-injection)
21 | * [Attributes](#Attributes)
22 | * [Fragments](#Fragments)
23 | * [References](#References)
24 | * [Components](#Components)
25 | * [Function component](#Function-component)
26 | * [Class component](#Class-component)
27 | * [Events](#Events)
28 | * [Conditional element](#Conditional-element)
29 | * [List of elements](#List-of-elements)
30 | * [Content projection](#Content-projection)
31 | * [Higher order component](#Higher-order-component)
32 | * [Routing](#Routing)
33 | * [Nested routing](#Nested-routing)
34 | * [Routing with parameters](#Routing-with-parameters)
35 | * [Authentication](#Authentication)
36 | * [State and life cycle](#State-and-life-cycle)
37 | * [State](#State)
38 | * [Life cycle](#Life-cycle)
39 | * [Forms](#Forms)
40 | * [Http requests](#Http-requests)
41 | * [Tests](#Tests)
42 | * [Interaction](#Interaction)
43 | * [Mocking http](#Mocking-http)
44 | * [Mocking components](#Mocking-components)
45 | * [Context](#Context)
46 | * [Hooks](#Hooks)
47 | * [Basic hooks](#Basic-hooks)
48 | * [Other hooks](#Other-hooks)
49 | * [Custom hook](#Custom-hook)
50 | * [TypeScript in React](#TypeScript-in-React)
51 | * [Add to project commands](#Add-to-project-commands)
52 | * [Add type for custom DOM element](#Add-type-for-custom-DOM-element)
53 | * [Interview questions](#Interview-questions)
54 |
55 |
56 |
57 | Basic React commands
58 | =================
59 |
60 | | Command | Notes |
61 | | ------------- | ------------- |
62 | | npx create-react-app {app name} | Create new React app |
63 | | npm run build | Build React app - create a folder with files ready for deployment |
64 | | npm start | Run project locally |
65 | | npm test | run tests in React app |
66 | | npm eject | remove the single build dependency from your project |
67 |
68 |
69 |
70 | JSX
71 | =================
72 |
73 | JSX allows us to write HTML elements in JavaScript and place them in the DOM. Basically, it converts HTML tags into react elements.
74 |
75 | ## Injection JS into HTML
76 |
77 | ```jsx
78 | const value = 'Hello world';
79 | return (
{value}
);
80 | ```
81 | 'Hello world' will be injected and displayed inside `
` element
82 |
83 | ## Element declaration
84 |
85 | ```jsx
86 | const value = 'Hello World';
87 | const element =
{value}
;
88 | return (element);
89 | ```
90 | We can assign specific DOM fragments to a particular variable (element above) and then (re)use it everywhere.
91 |
92 | ## Function injection
93 |
94 | ```jsx
95 | function addNumbers(x1, x2) {
96 | return x1 + x2;
97 | }
98 | const element =
{addNumbers(2, 5)}
99 | ```
100 | Not only string values can be injected into DOM. The result of the above case will be div with 7 inside it as addNumbers was injected into an element.
101 |
102 | ## Attributes
103 | ```jsx
104 | const avatarUrl = "img/picture.jpg"
105 | const element = ;
106 | ```
107 | JavaScript code can be also called for DOM element properties/events
108 |
109 | ## Fragments
110 | JSX syntax must have one top parent HTML element. When we don't want to pack our HTML into (for example) one div or other elements then we can use `fragment` which won't be rendered in our HTML
111 |
112 | Example:
113 | ```jsx
114 |
115 |
126 | >
127 |
128 | ```
129 |
130 | ## References
131 | We can refer to html element from JS
132 |
133 | 1. Declare a reference
134 | ```js
135 | this.element = React.createRef();
136 | ```
137 |
138 | 2. Assign a reference to element
139 | ```jsx
140 |
141 | ```
142 |
143 | 3. Use reference to interact with element
144 | ```js
145 | this.element.current.focus();
146 | ```
147 |
148 | Tip: References works for the class component but not for function component (unless you use useRef hook, see [Other hooks](https://github.com/delprzemo/react-cheatsheet#other-hooks "other-hooks") )
149 |
150 | Components
151 | =================
152 |
153 | "React lets you define components as classes or functions. Components defined as classes currently provide more features"
154 |
155 | ## Function component
156 |
157 | Sample component:
158 | ```js
159 | function App() {
160 | return
}
297 | ```
298 |
299 | ## List of elements
300 |
301 | The recommended way to show a list of the same components is to use the "map" function. Example:
302 | ```js
303 | const numbers = [1, 2, 3, 4, 5];
304 | const listItems = numbers.map((numer, index) =>
305 |
306 | {number}
307 |
308 | );
309 |
310 | ```
311 | Then just use `listItems` element in your JSX DOM.
312 | Please note `key` property inside - it is obligatory to identify particular row in list.
313 |
314 | ## Content projection
315 |
316 | Content projection is injecting some HTML from parent component to child component
317 |
318 | Example:
319 |
320 | Parent component:
321 | ```jsx
322 |
` will be injected to place where `{this.props.children}` has been used, so MyElement will look like:
333 |
334 | ```jsx
335 |
336 |
Hello world
337 |
338 | ```
339 |
340 | ## Higher order component
341 | Create a parameterized component in order to reuse it in different ways.
342 |
343 | Example:
344 | ```jsx
345 | const myHoc = settings => WrappedComponent => {
346 | return class DecoratingComponent extends React.Component {
347 | render() {
348 | return (
)
349 | }
350 | }
351 | }
352 | ```
353 |
354 | Usage:
355 | ```jsx
356 | const MyWrappedComponent = myHoc('test')(SomeComponent);
357 |
358 | ```
359 | `test` will be injected into className
360 |
361 |
362 | Routing
363 | =================
364 | The Router will be described with react-router-dom library usage, which is often recommended.
365 |
366 | Install:
367 | ```
368 | npm install react-router-dom
369 | ```
370 |
371 | Sample presenting an area where components matching to current URL will be rendered:
372 |
373 | ```jsx
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 | ```
383 |
384 | Link changing current url:
385 |
386 | ```jsx
387 | List
388 | ```
389 |
390 | Tip: Route and Link need to be in same Router element
391 |
392 | ## Nested routing
393 |
394 | Parent:
395 | ```jsx
396 |
397 | ```
398 |
399 | SomeComponent:
400 | ```js
401 | function SomeComponent({ match }) {
402 | return (
403 |
404 |
405 |
406 |
407 |
408 | )
409 | }
410 | ```
411 |
412 | ## Routing with parameters
413 |
414 | ```jsx
415 |
416 | ```
417 |
418 | and then in SomeComponent we have access to:
419 |
420 | ```jsx
421 | {match.params.id}
422 | ```
423 |
424 | ## Authentication
425 |
426 | Good idea is to create a custom Route component that will show specific component only when our authentication logic is passed:
427 |
428 | ```jsx
429 | function PrivateRoute({ component: Component, ...rest }) {
430 | return (
431 | (_isAuthentictedLogic_) ?
432 | () :
433 | (
434 | )}
435 | />
436 | );
437 | }
438 | ```
439 |
440 | Then instead of Route use PrivateRoute
441 |
442 | ```jsx
443 |
444 | ```
445 |
446 |
447 | State and life cycle
448 | =================
449 |
450 | ## State
451 | The state decides about the update to a component’s object. When state changes, the component is re-rendered.
452 |
453 | Declaring initial state:
454 | ```js
455 | constructor() {
456 | this.state = { userId: 2, userName: "Jannice"};
457 | }
458 | ```
459 |
460 | Using state:
461 | ```jsx
462 |
{this.state.userName}
463 | ```
464 |
465 | Updating state:
466 | ```js
467 | this.setState({ userId: 3, userName: "Tom"});
468 | ```
469 | After setState component will be re-rendered
470 |
471 | ## Life cycle
472 |
473 | | Life cycle | Notes |
474 | | ------------- | ------------- |
475 | | componentDidMount | Called at the beginning of component life - when a component has been rendered |
476 | | componentWillUnmount | This method is called before the unmounting of the component takes place. |
477 | | componentWillUpdate | Before re-rendering component (after change) |
478 | | componentDidUpdate | After re-rendering component (after change) |
479 | | componentDidCatch | Called when an error has been thrown|
480 | | shouldComponentUpdate | Determines whether a component should be updated after a change or not |
481 | | getDerivedStateFromProps | Called at the beginning of component life and when props/state will change |
482 | | getSnapshotBeforeUpdate| Called just before rerendering component - in order to save state|
483 |
484 | **Note** Deprecation alert for componentWillUnmount and componentWillUpdate. This can cause memory leaks for server rendering.
485 |
486 |
487 | Example:
488 | ```jsx
489 | componentDidMount() {
490 | console.log("componentDidMount")
491 | // some logic here
492 | }
493 |
494 | componentWillUnmount() {
495 | console.log("componentWillUnmount")
496 | // some logic here
497 | }
498 | ```
499 |
500 | Forms
501 | =================
502 |
503 | Sample form:
504 |
505 | ```js
506 | onValueChange = (event) => {
507 | this.setState({ value: event.target.value });
508 | }
509 | ```
510 | ```js
511 | onSubmit = (e) => {
512 | e.preventDefault();
513 | // Submit logic
514 | }
515 |
516 | ```
517 | ```jsx
518 |
526 | ```
527 |
528 | Validation is described here: https://webfellas.tech/#/article/5
529 |
530 | Http requests
531 | =================
532 |
533 | There are a lot of ways to communicate with our backend API. One of them is to use Axios library.
534 |
535 | Install:
536 | `npm install axios`
537 |
538 | Example with GET:
539 | ```js
540 | axios.get('/user', {
541 | params: {ID: 12345}
542 | }).then(function (response) {
543 | //some logic here
544 | })
545 | .catch(function (error) {
546 | //some logic here
547 | })
548 | .finally(function () {
549 | //some logic here
550 | });
551 | ```
552 |
553 | Example with POST:
554 | ```js
555 | axios.post('/user', {
556 | firstName: 'Fred',
557 | id: 2
558 | }).then(function (response) {
559 | //some logic here
560 | })
561 | .catch(function (error) {
562 | //some logic here
563 | });
564 | ```
565 |
566 | Example with async call:
567 | ```js
568 | const response = await axios.get('/user?ID=12345');
569 | ```
570 |
571 | Tests
572 | =================
573 |
574 | Useful libs:
575 |
576 | `npm install --save-dev jest` to run tests
577 |
578 | `npm install --save-dev @testing-library/react` set of functions that may be useful for tests in React
579 |
580 | Sample tests:
581 |
582 | ```jsx
583 | let container = null;
584 | beforeEach(() => {
585 | container = document.createElement("div");
586 | document.body.appendChild(container);
587 | });
588 | afterEach(() => {
589 | unmountComponentAtNode(container);
590 | container.remove();
591 | container = null;
592 | });
593 | it("renders menu with Help", () => {
594 | act(() => {
595 | render(, container);
596 | });
597 | expect(container.textContent).toBe("Some text inside");
598 | });
599 |
600 | ```
601 |
602 | ## Interaction
603 |
604 | Click on element:
605 | ```js
606 | import { fireEvent } from '@testing-library/react'
607 | ```
608 | ```js
609 | fireEvent.click(container.querySelector('.some-class));
610 | ```
611 |
612 | Change value in input:
613 | ```js
614 | fireEvent.change(container.querySelector('.some-class)), {
615 | target: { value: "12345" }
616 | });
617 | ```
618 |
619 | Check if element contains class
620 | ```js
621 | expect(someEl.classList.contains('disabled')).toBe(false);
622 | ```
623 |
624 | ## Mocking http
625 |
626 | `npm install axios-mock-adapter --save-dev`
627 |
628 | Example:
629 | ```js
630 | var axios = require('axios');
631 | var MockAdapter = require('axios-mock-adapter');
632 | var mock = new MockAdapter(axios);
633 |
634 | ```
635 | ```js
636 | mock.onGet('/users').reply(200, {
637 | users: [
638 | { id: 1, name: 'John Smith' }
639 | ]
640 | });
641 | ```
642 |
643 | With specific parameter
644 | ```js
645 | mock.onGet('/users', { params: { searchText: 'John' } }).reply()
646 | ```
647 |
648 | ## Mocking components
649 | Example:
650 | ```js
651 | jest.mock("./SomeComponent", () => {
652 | return function DummyComponent(props) {
653 | return (
654 |
655 | here is square
656 |
657 | );
658 | };
659 | });
660 |
661 | ```
662 |
663 | Context
664 | =================
665 |
666 | Context is a "bag" for some data common for node of components.
667 |
668 | Declare context:
669 | ```js
670 | import React from 'react';
671 | export const ColorContext = React.createContext('red');
672 | ```
673 | 'red' is default value
674 |
675 | Create context and distribute it to child component:
676 | ```jsx
677 | const { Provider } = ColorContext;
678 | return (
679 |
680 |
681 |
682 | );
683 | ```
684 |
685 | Use it in child component:
686 | ```js
687 | const { Consumer } = ColorContext;
688 | return (
689 |
690 | {value =>
{value}
}
691 |
692 | )
693 | ```
694 |
695 | Use it in child component outside render function:
696 | ```js
697 | static contextType = ColorContext;
698 | let value = this.context.value
699 | ```
700 |
701 | Hooks
702 | =================
703 | Hooks let us use in functions React features dedicated previously for only classes, like state.
704 |
705 |
706 | ## Basic hooks
707 |
708 | **useState hook**
709 |
710 | Can replace state managment
711 | ```js
712 | const [count, setCount] = useState(0);
713 | ```
714 | `count` can be used to read data
715 |
716 | `0` is the default value for count
717 |
718 | `setCount(10)` is a function to change count state value
719 |
720 | **useEffect hook**
721 |
722 | Can replace `componentDidMount`, `componentDidUpdate`, `componentWillUnmount` and other life cycle component events
723 |
724 | Instead of using componentDidMount, componentDidUpdate we can use useEffect hook like this:
725 | ```js
726 | useEffect(() => {
727 | document.title = `Clicked ${count}`;
728 | });
729 | ```
730 |
731 | In order to act as componentWillUnmount:
732 | ```js
733 | useEffect(() => {
734 | return () => {/*unsubscribe*/};
735 | });
736 | ```
737 |
738 |
739 | **useContext hook**
740 |
741 | Hooks for context implementation. See [Context](https://github.com/delprzemo/react-cheatsheet#context "context")
742 |
743 | Parent:
744 | ```jsx
745 | const CounterContext = React.createContext(counter);
746 |
747 | function App() {
748 | return (
749 |
750 |
751 |
752 | );
753 | }
754 | ```
755 |
756 | Child:
757 | ```jsx
758 | const counter = useContext(CounterContext);
759 | ```
760 |
761 | ## Other hooks
762 |
763 | | Hook | Usage | Notes |
764 | | ------------- | ------------- | ------------- |
765 | | useReducer | const [state, dispatch] = useReducer(reducer, initialArg, init); | Used for redux |
766 | | useCallback | const memoizedCallback = useCallback(() => {doSomething(a, b);},[a, b],); | Returns a memoized callback |
767 | | useMemo | const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); | Returns a memoized value. |
768 | | useRef | const refContainer = useRef(initialValue); | Hooks for element reference |
769 | | useDebugValue | useDebugValue(value) | Display information in React DevTools |
770 |
771 | ## Custom hook
772 | Custom hooks can be created.
773 | Sample implementation:
774 | ```jsx
775 | function useColor(initialColor) {
776 | const [color, changeColor] = useState(initialColor);
777 | function change(color) {
778 | changeColor(color);
779 | }
780 | useEffect(() => {
781 | console.log('Color changed');
782 | });
783 | return [color, change];
784 | }
785 |
786 | ```
787 |
788 |
789 | TypeScript in React
790 | =================
791 |
792 | ## Add to project commands
793 |
794 | `npx create-react-app my-app --typescript` - new app with TypeScript
795 |
796 | `npm install --save typescript @types/node @types/react @types/react-dom @types/jest` - add TypeScript to existing project
797 |
798 | `npx tsc --init` - init tsconfig
799 |
800 | ## Add type for custom DOM element
801 |
802 | ```ts
803 | declare namespace JSX {
804 | interface IntrinsicElements {foo: any}
805 | }
806 | ; // ok
807 | ; // error
808 | ```
809 |
810 |
811 | Interview questions
812 | =================
813 |
814 | **Q: How can we declare the component??**
815 |
816 | A: Use class extending React.Component or use function with React.FC type returning JSX.
817 |
818 | **Q: What is a difference between function component and class component?**
819 |
820 | A: Components defined as classes currently provide more features. Anyway, hooks can change that.
821 |
822 | **Q: In what type of component can we use hooks?**
823 |
824 | A: Function component
825 |
826 | **Q: How can we inject some HTML from parent component to child component?**
827 |
828 | A: Using content projection - > this.props.children will keep parent html element.
829 | See [Content projection](https://github.com/delprzemo/react-cheatsheet#content-projection "content-projection")
830 |
831 | **Q: Describe useEffect hook**
832 |
833 | A: UseEffect can replace componentDidMount, componentDidUpdate, componentWillUnmount and other life cycle component events.
834 | See [Basic hooks](https://github.com/delprzemo/react-cheatsheet#basic-hooks "Basic-hooks")
835 |
836 | **Q: What is the difference between state and props??**
837 |
838 | A: The state decides about the update to a component’s object. When state changes, the component is re-rendered.
839 | Props are parameters passed from parent component to child component.
840 |
841 | **Q: What is a higher-order component??**
842 |
843 | A: Basically its's parameterized component. It allows reusing of a particular component in many ways.
844 | Sample implementation:
845 | ```jsx
846 | const myHoc = settings => WrappedComponent => {
847 | return class DecoratingComponent extends React.Component {
848 | render() {
849 | return (
)
850 | }
851 | }
852 | }
853 | ```
854 |
855 | usage:
856 | ```jsx
857 | const MyWrappedComponent = myHoc('test')(SomeComponent);
858 |
859 | ```
860 |
861 | **Q: What is JSX?**
862 |
863 | A: JSX allows us to write HTML elements in JavaScript and place them in the DOM. Basically, it converts HTML tags into react elements. See [JSX](https://github.com/delprzemo/react-cheatsheet#JSX "JSX")
864 |
865 | **Q: How can we create new react app?**
866 |
867 | A: Using command `npx create-react-app {app name}`
868 |
869 | **Q: What will be the result of `npm eject`?**
870 |
871 | A: Webpack for React application won't be handled automatically anymore. We will have access to Webpack configuration files in order to customize it to our needs.
872 |
873 |
874 |
--------------------------------------------------------------------------------