29
loading...
This website collects cookies to deliver better user experience
function App(count) {
console.log('Counter initialized with ' + count);
return function print() {
console.log(++count);
};
}
let print = App(1);
print();
print();
print();
print = App(5);
print();
print();
Counter initialized with 1
2
3
4
Counter initialized with 5
6
7
App
function returns another function called print
this makes our App
, a higher order function. Any function that returns another function or that takes a function as argument is called as Higher order function.
function App(count) {
console.log('Counter initialized with ' + count);
return function print() {
console.log(++count);
};
}
print
closes over the variable count
which is from its outer scope. This closing is referred to as closure. function App(count) {
console.log('Counter initialized with ' + count);
return function increment() {
console.log(++count);
};
}
let someRandomName = App(1);
someRandomName(); //logs 2
increment
and we are assigning it to the variable someRandomName
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. ~ MDN
A closure is a function having access to the parent scope, even after the parent function has closed. ~ W3Schools
App
function, we get the print
function in return.let print = App(1);
App
function gets count as 1 and returns print
which simply increases the count and logs it. So each time when print
is called, the count is incremented and printed.function App() {
let count = 0;
function increment() {
count = count + 1;
}
let message = `Count is ${count}`;
function log() {
console.log(message);
}
return [increment, log];
}
let [increment, log] = App();
increment();
increment();
increment();
log();
count
and message
in our App.increment
and log
. increment
increases our count
and log
simply logs the message
. Count is 0
increment
functionfunction App() {
let count = 0;
function increment() {
count = count + 1;
console.log(count);
}
let message = `Count is ${count}`;
function log() {
console.log(message);
}
return [increment, log];
}
let [increment, log] = App();
increment();
increment();
increment();
log();
1
2
3
Count is 0
count
that is present in the lexical scope of increment
. However, the problem is with the message
and log
.log
function captured the message
variable and kept it. So, when we increment the count, the message
is not updated and our log
returns the message "Count is 0".log
function App() {
let count = 0;
function increment() {
count = count + 1;
console.log(count);
}
function log() {
let message = `Count is ${count}`;
console.log(message);
}
return [increment, log];
}
let [increment, log] = App();
increment();
increment();
increment();
log();
1
2
3
Count is 3
function App() {
const [count, setCount] = React.useState(0);
let message = `Count is ${count}`;
React.useEffect(() => {
if (count === 3) {
console.log(message);
}
}, []);
return (
<div className="App">
<h1>{count}</h1>
<button
onClick={() => {
setCount((c) => c + 1);
}}
>
Increment
</button>
</div>
);
}
Increment
button three times, we should have a log that says "Count is 3".message
does get updated, but our useEffect
just failed to capture the updated message. count
and message
as our dependency array.function App() {
const [count, setCount] = React.useState(0);
let message = `Count is ${count}`;
React.useEffect(() => {
if (count === 3) {
console.log(message);
}
}, [count, message]);
return (
<div className="App">
<h1>{count}</h1>
<button
onClick={() => {
setCount((c) => c + 1);
}}
>
Increment
</button>
</div>
);
}
count
is updated, message
does get updated, so specifying just either of those is fine to get the expected output. All of our dependencies for hooks must be specified in the dependency array and, we should not lie to React about dependencies
eslint-plugin-react-hooks
to capture all possible errors with the usage of hooks.react-scripts
>= 3.0)useEffect
, we would run into the same problem with other hooks as well like useMemo
and useCallback
.🚫 Don't Lie to React about Dependencies and 🚫 Don't disable this ESLint rule 🤷🏾♂️