Skip to content
This repository was archived by the owner on Nov 12, 2023. It is now read-only.

Commit d7698a8

Browse files
committed
30. Invoking the useEffect callback only after mount
1 parent ae664f6 commit d7698a8

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [Refactor to Compound components](#refactor-to-compound-components)
2727
- [Alternative export strategy](#alternative-export-strategy)
2828
- [Exposing state via a callback](#exposing-state-via-a-callback)
29+
- [Invoking the useEffect callback only after mount!](#invoking-the-useeffect-callback-only-after-mount)
2930
- [**Section 5: Patterns for Crafting Reusable Styles**](#section-5-patterns-for-crafting-reusable-styles)
3031
- [**Section 6: The Control Props Pattern**](#section-6-the-control-props-pattern)
3132
- [**Section 7: Custom Hooks: A Deeper Look at the Foundational Pattern**](#section-7-custom-hooks-a-deeper-look-at-the-foundational-pattern)
@@ -1248,6 +1249,28 @@ const Usage = () => {
12481249
12491250
**[⬆ back to top](#table-of-contents)**
12501251
1252+
### Invoking the useEffect callback only after mount!
1253+
1254+
[useRef](https://reactjs.org/docs/hooks-reference.html#useref)
1255+
1256+
```javascript
1257+
// 1. default value is false
1258+
// 1. set to true when MediumClap is rendered
1259+
const componentJustMounted = useRef(false)
1260+
useEffect(() => {
1261+
if(componentJustMounted.current){
1262+
// 3. next time count changes
1263+
console.log('onClap is called')
1264+
onClap && onClap(clapState)
1265+
} else {
1266+
// 2. set to true the first time in useEffect after rendered
1267+
componentJustMounted.current = true
1268+
}
1269+
}, [count])
1270+
```
1271+
1272+
**[⬆ back to top](#table-of-contents)**
1273+
12511274
## **Section 5: Patterns for Crafting Reusable Styles**
12521275
12531276
**[⬆ back to top](#table-of-contents)**

showcase/src/patterns/03.js

+29-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import React, {
55
createContext,
66
useMemo,
77
useContext,
8-
useEffect
8+
useEffect,
9+
useRef
910
} from 'react'
1011
import mojs from 'mo-js'
1112
import styles from './index.css'
@@ -120,15 +121,14 @@ const useClapAnimation = ({
120121
return animationTimeline;
121122
}
122123

123-
// 1. MediumClapContext lets us pass a value deep into
124-
// the tree of React components in MediumClap component
124+
// MediumClapContext lets us pass a value deep into the tree of React components in MediumClap component
125125
const MediumClapContext = createContext()
126126

127-
// 2. Use a Provider to pass the current value to the tree below.
127+
// Use a Provider to pass the current value to the tree below.
128128
// Any component can read it, no matter how deep it is.
129129
const { Provider } = MediumClapContext
130130

131-
// 5. MediumClap component don’t know their children ahead of time.
131+
// MediumClap component don’t know their children ahead of time.
132132
// Use the special children prop to pass children elements directly into MediumClap
133133
const MediumClap = ({ children, onClap }) => {
134134
const MAXIMUM_USER_CLAP = 50
@@ -149,8 +149,18 @@ const MediumClap = ({ children, onClap }) => {
149149
clapCountTotalEl: clapCountTotalRef
150150
})
151151

152+
// 1. default value is false
153+
// 1. set to true when MediumClap is rendered
154+
const componentJustMounted = useRef(false)
152155
useEffect(() => {
153-
onClap && onClap(clapState)
156+
if(componentJustMounted.current){
157+
// 3. next time count changes
158+
console.log('onClap is called')
159+
onClap && onClap(clapState)
160+
} else {
161+
// 2. set to true the first time in useEffect after rendered
162+
componentJustMounted.current = true
163+
}
154164
}, [count])
155165

156166
const handleClapClick = () => {
@@ -165,7 +175,7 @@ const MediumClap = ({ children, onClap }) => {
165175
}))
166176
}
167177

168-
// 3. Returns a memoized state.
178+
// Returns a memoized state.
169179
const memoizedValue = useMemo(
170180
() => ({
171181
...clapState,
@@ -174,9 +184,8 @@ const MediumClap = ({ children, onClap }) => {
174184
)
175185

176186
return (
177-
// 4. Accepts a value prop to be passed to consuming components
178-
// that are descendants of this Provider.
179-
// 5. MediumClap component don’t know their children ahead of time.
187+
// Accepts a value prop to be passed to consuming components that are descendants of this Provider.
188+
// MediumClap component don’t know their children ahead of time.
180189
// Use the special children prop to pass children elements directly into MediumClap
181190
<Provider value={memoizedValue}>
182191
<button
@@ -192,7 +201,7 @@ const MediumClap = ({ children, onClap }) => {
192201
}
193202

194203
const ClapIcon = () => {
195-
// 6. Get prop from MediumClapContext instead from parent MediumClap
204+
// Get prop from MediumClapContext instead from parent MediumClap
196205
const { isClicked } = useContext(MediumClapContext)
197206
return (
198207
<span>
@@ -209,7 +218,7 @@ const ClapIcon = () => {
209218
}
210219

211220
const ClapCount = () => {
212-
// 6. Get prop from MediumClapContext instead from parent MediumClap
221+
// Get prop from MediumClapContext instead from parent MediumClap
213222
const { count, setRef } = useContext(MediumClapContext)
214223
return (
215224
<span
@@ -223,7 +232,7 @@ const ClapCount = () => {
223232
}
224233

225234
const ClapCountTotal = () => {
226-
// 6. Get prop from MediumClapContext instead from parent MediumClap
235+
// Get prop from MediumClapContext instead from parent MediumClap
227236
const { countTotal, setRef } = useContext(MediumClapContext)
228237
return (
229238
<span
@@ -241,22 +250,27 @@ MediumClap.Count = ClapCount
241250
MediumClap.Total = ClapCountTotal
242251
// import MediumClap, { Icon, Count, Total } from 'medium-clap'
243252

244-
// 5. MediumClap component don’t know their children ahead of time.
253+
// MediumClap component don’t know their children ahead of time.
245254
// Use the special children prop to pass children elements directly into MediumClap
246255
const Usage = () => {
247256
// expose count, countTotal and isClicked
248257
const [count, setCount] = useState(0)
249258
const handleClap = (clapState) => {
250259
setCount(clapState.count)
251260
}
261+
// count = 0
262+
// !count = true
263+
// !!count = false
252264
return (
253265
<div style={{ width: '100%' }}>
254266
<MediumClap onClap={handleClap}>
255267
<MediumClap.Icon />
256268
<MediumClap.Count />
257269
<MediumClap.Total />
258270
</MediumClap>
259-
<div className={styles.info}>{`You have clapped ${count}`}</div>
271+
{!!count && (
272+
<div className={styles.info}>{`You have clapped ${count} times`}</div>
273+
)}
260274
</div>
261275
)
262276
}

0 commit comments

Comments
 (0)