13 |
16 | modalInstance = modal}>
17 | Good lights appear gathering for don't under. Together third his multiply without multiply over herb. Us was fish from of said a abundantly void signs is fish replenish very heaven own of it stars.
18 |
19 |
34 | Days. All in herb moving our stars, give. Whose moving which unto, second. Given dry. Evening the, i one together us be replenish herb sea subdue midst cattle night in shall fruit. Saying green moveth. Heaven. Moving to second. For his saw together thing night form greater. That winged over forth under. Living which. Whose day were creeping in appear every heaven appear own upon good morning fill third you're moved won't lesser beast won't fill dry fourth him a Have yielding seasons over may brought seed called divided can't first fifth divided gathered heaven waters tree from thing beginning.
35 |
14 | Days. All in herb moving our stars, give. Whose moving which unto, second. Given dry. Evening the, i one together us be replenish herb sea subdue midst cattle night in shall fruit. Saying green moveth. Heaven. Moving to second. For his saw together thing night form greater. That winged over forth under. Living which. Whose day were creeping in appear every heaven appear own upon good morning fill third you're moved won't lesser beast won't fill dry fourth him a Have yielding seasons over may brought seed called divided can't first fifth divided gathered heaven waters tree from thing beginning.
15 |
12 |
15 | {isOpen && (
16 |
17 | Good lights appear gathering for don't under. Together third his multiply without multiply over herb. Us was fish from of said a abundantly void signs is fish replenish very heaven own of it stars.
18 |
19 | )}
20 |
14 | Days. All in herb moving our stars, give. Whose moving which unto, second. Given dry. Evening the, i one together us be replenish herb sea subdue midst cattle night in shall fruit. Saying green moveth. Heaven. Moving to second. For his saw together thing night form greater. That winged over forth under. Living which. Whose day were creeping in appear every heaven appear own upon good morning fill third you're moved won't lesser beast won't fill dry fourth him a Have yielding seasons over may brought seed called divided can't first fifth divided gathered heaven waters tree from thing beginning.
15 |
16 |
17 | )
18 | }
19 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/10-pass-refs-to-child-components-using-the-function-as-a-child-pattern/SizeTracker.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const SizeTracker = ({ children }) => {
4 | const [width, setWidth] = React.useState(0);
5 |
6 | const resizeCallback = React.useCallback((entries) => {
7 | entries.forEach((entry) => {
8 | const rect = entry.target.getBoundingClientRect();
9 | setWidth(rect.width);
10 | });
11 | }, []);
12 |
13 | const resizeObserver = React.useMemo(() => new ResizeObserver(resizeCallback), []);
14 |
15 | const trackSize = (ele) => {
16 | if (ele) {
17 | resizeObserver.observe(ele);
18 | }
19 | };
20 |
21 | React.useEffect(() => {
22 | return () => {
23 | resizeObserver.disconnect();
24 | };
25 | }, []);
26 |
27 | return children({
28 | ref: trackSize,
29 | width,
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/10-pass-refs-to-child-components-using-the-function-as-a-child-pattern/pass-refs-child-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phuocng/master-of-react-ref/082b7c02321fff9c6843a5a1b63edd1f5ec68149/10-pass-refs-to-child-components-using-the-function-as-a-child-pattern/pass-refs-child-components.png
--------------------------------------------------------------------------------
/11-create-a-reference-using-react-create-ref/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Collapse } from './Collapse';
3 |
4 | export default App = () => {
5 | return (
6 |
7 | In grass us behold. Earth made second dry beginning creeping give fly moveth Green very fly living Together it second tree. Shall night open created seas creeping void whose fowl upon, our you'll their him together herb, void tree divide face us seed grass saying is which grass. Was shall. Male you'll wherein replenish have upon face shall together first sea created dominion yielding subdue evening over you also don't god great creeping hath moved. Midst is fish was winged multiply one, i firmament very winged created fill saw void also form bearing days moveth. Grass for male moved very you night life. Us seas firmament may fowl dominion abundantly said face the. Set also. Make, it. Said moving replenish bring void set won't years moving. Be life. Don't lights it behold saw fourth signs above forth fly which light god and for called, air saying is of stars our they're dry good creature creepeth gathered. Created it winged god moving herb place our rule abundantly Our brought so sixth land stars wherein. That i. Lesser under, was divided fowl void kind appear and fifth sixth heaven green creeping can't herb isn't lights tree. Dry night kind man bearing is.
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/11-create-a-reference-using-react-create-ref/Collapse.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | class Collapse extends React.Component {
4 | constructor(props) {
5 | super(props);
6 | this.state = {
7 | isOpened: false,
8 | };
9 | this.bodyRef = React.createRef();
10 | this.contentRef = React.createRef();
11 | this.handleToggle = this.handleToggle.bind(this);
12 | this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
13 | }
14 |
15 | componentDidMount() {
16 | const bodyEle = this.bodyRef.current;
17 | bodyEle.style.height = `${bodyEle.clientHeight}px`;
18 | }
19 |
20 | handleToggle() {
21 | const { isOpened } = this.state;
22 | const bodyEle = this.bodyRef.current;
23 | const contentEle = this.contentRef.current;
24 |
25 | if (!isOpened) {
26 | bodyEle.classList.remove('truncate');
27 | bodyEle.style.height = `${contentEle.scrollHeight}px`;
28 | } else {
29 | contentEle.classList.add('truncate');
30 | const newHeight = contentEle.clientHeight;
31 | contentEle.classList.remove('truncate');
32 | bodyEle.classList.add('item__body--fading');
33 | bodyEle.style.height = `${newHeight}px`;
34 | }
35 | }
36 |
37 | handleTransitionEnd() {
38 | this.setState((prevState) => ({
39 | isOpened: !prevState.isOpened,
40 | }));
41 | }
42 |
43 | render() {
44 | const { isOpened } = this.state;
45 |
46 | return (
47 |
65 | );
66 | });
67 |
--------------------------------------------------------------------------------
/22-expose-methods-of-a-component-using-use-imperative-handle/styles.css:
--------------------------------------------------------------------------------
1 | .slider {
2 | overflow: hidden;
3 | position: relative;
4 | width: 100%;
5 | height: 20rem;
6 | }
7 | .slider__inner {
8 | position: absolute;
9 | top: 0;
10 | left: 0;
11 | width: 100%;
12 | height: 100%;
13 | }
14 | .slider__item {
15 | position: absolute;
16 | top: 0;
17 | left: 0;
18 | width: 100%;
19 | height: 100%;
20 |
21 | /* Demo purpose */
22 | background: rgb(241 245 249);
23 | align-items: center;
24 | display: flex;
25 | justify-content: center;
26 | font-size: 2.5rem;
27 | font-weight: 500;
28 | }
29 |
30 | .container {
31 | position: relative;
32 | }
33 |
34 | .container__navigation {
35 | position: absolute;
36 | bottom: 1rem;
37 | left: 50%;
38 | transform: translateX(-50%);
39 |
40 | align-items: center;
41 | display: flex;
42 | justify-content: center;
43 | gap: 0.5rem;
44 | }
45 | .container__dot {
46 | background: rgb(203 213 225);
47 | border-radius: 50%;
48 | cursor: pointer;
49 |
50 | height: 0.5rem;
51 | width: 0.5rem;
52 | }
53 | .container__dot--active {
54 | background: rgb(100 116 139);
55 | }
56 |
57 | .container__prev,
58 | .container__next {
59 | position: absolute;
60 | top: 50%;
61 | transform: translateY(-50%);
62 | height: 1rem;
63 | width: 0.5rem;
64 | }
65 | .container__prev::before,
66 | .container__next::before {
67 | cursor: pointer;
68 | content: '';
69 | position: absolute;
70 | border-style: solid;
71 | height: 0;
72 | width: 0;
73 | }
74 | .container__prev::before {
75 | border-color: transparent rgb(148 163 184) transparent transparent;
76 | border-width: 0.5rem 0.5rem 0.5rem 0;
77 | }
78 | .container__next::before {
79 | border-color: transparent transparent transparent rgb(148 163 184);
80 | border-width: 0.5rem 0 0.5rem 0.5rem;
81 | }
82 | .container__prev {
83 | left: 0.5rem;
84 | }
85 | .container__next {
86 | right: 0.5rem;
87 | }
88 |
--------------------------------------------------------------------------------
/22-expose-methods-of-a-component-using-use-imperative-handle/use-imperative-handle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phuocng/master-of-react-ref/082b7c02321fff9c6843a5a1b63edd1f5ec68149/22-expose-methods-of-a-component-using-use-imperative-handle/use-imperative-handle.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 phuocng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Master of React ref
2 |
3 | React Ref is a fantastic feature in React that allows you to directly access and manipulate DOM (Document Object Model) elements.
4 | In simpler terms, it's a way to reference a specific element in your React app, giving you the power to modify and interact with it outside of the normal React data flow.
5 |
6 | This series is your ultimate guide to mastering the use of ref in React.
7 | We'll start with the basics, such as string and callback ref, and then dive into more advanced topics like the `useRef()` hook and `forwardRef()` API.
8 | By the end, you'll have a deep understanding of how to use ref like a pro in your React applications.
9 | Get ready to take your React skills to the next level!
10 |
11 | - [01: Access a component's underlying DOM node with findDOMNode()](https://phuoc.ng/collection/react-ref/access-a-component-underlying-dom-node-with-find-dom-node/)
12 |
13 | 
14 |
15 | - [02: String refs](https://phuoc.ng/collection/react-ref/string-refs/)
16 |
17 | 
18 |
19 | - [03: Store a reference with callback refs](https://phuoc.ng/collection/react-ref/store-a-reference-with-callback-refs/)
20 |
21 | 
22 |
23 | - [04: Access the methods of class components](https://phuoc.ng/collection/react-ref/access-the-methods-of-class-components/)
24 |
25 | 
26 |
27 | - [05: Use callback refs to access individual elements in a list](https://phuoc.ng/collection/react-ref/use-callback-refs-to-access-individual-elements-in-a-list/)
28 |
29 | 
30 |
31 | - [06: Implement a basic container query with callback refs](https://phuoc.ng/collection/react-ref/implement-a-basic-container-query-with-callback-refs/)
32 |
33 | 
34 |
35 | - [07: Save the element passed to a callback ref as a state](https://phuoc.ng/collection/react-ref/save-the-element-passed-to-a-callback-ref-as-a-state/)
36 |
37 | 
38 |
39 | - [08: Create a custom hook returning a callback ref](https://phuoc.ng/collection/react-ref/create-a-custom-hook-returning-a-callback-ref/)
40 |
41 | 
42 |
43 | - [09: Make an element draggable](https://phuoc.ng/collection/react-ref/make-an-element-draggable/)
44 |
45 | 
46 |
47 | - [10: Pass refs to child components using the function as a child pattern](https://phuoc.ng/collection/react-ref/pass-refs-to-child-components-using-the-function-as-a-child-pattern/)
48 |
49 | 
50 |
51 | - [11: Create a reference using React.createRef()](https://phuoc.ng/collection/react-ref/create-a-reference-using-react-create-ref/)
52 |
53 | 
54 |
55 | - [12: Reference an element with React's useRef() hook](https://phuoc.ng/collection/react-ref/reference-an-element-with-react-use-ref-hook/)
56 |
57 | 
58 |
59 | - [13: Build your own drawing board](https://phuoc.ng/collection/react-ref/build-your-own-drawing-board/)
60 |
61 | 
62 |
63 | - [14: Drag and drop items within a list](https://phuoc.ng/collection/react-ref/drag-and-drop-items-within-a-list/)
64 |
65 | 
66 |
67 | - [15: Persist values between renders](https://phuoc.ng/collection/react-ref/persist-values-between-renders/)
68 |
69 | 
70 |
71 | - [16: Save the previous value of a variable](https://phuoc.ng/collection/react-ref/save-the-previous-value-of-a-variable/)
72 |
73 | 
74 |
75 | - [17: Detect whether an element is in view](https://phuoc.ng/collection/react-ref/detect-whether-an-element-is-in-view/)
76 |
77 | 
78 |
79 | - [18: Pass a ref to a custom hook](https://phuoc.ng/collection/react-ref/pass-a-ref-to-a-custom-hook/)
80 |
81 | 
82 |
83 | - [19: Merge different refs](https://phuoc.ng/collection/react-ref/merge-different-refs/)
84 |
85 | 
86 |
87 | - [20: Build a tooltip component](https://phuoc.ng/collection/react-ref/build-a-tooltip-component/)
88 |
89 | 
90 |
91 | - [21: Pass a ref to a child component using forwardRef()](https://phuoc.ng/collection/react-ref/pass-a-ref-to-a-child-component-using-forward-ref/)
92 |
93 | 
94 |
95 | - [22: Expose methods of a component using useImperativeHandle()](https://phuoc.ng/collection/react-ref/expose-methods-of-a-component-using-use-imperative-handle/)
96 |
97 | 
98 |
--------------------------------------------------------------------------------