@@ -18,18 +18,35 @@ const fetchTodosFromApi = async () => {
18
18
const TodoList = ( ) => {
19
19
const [ todos , setTodoList ] = useState ( [ ] ) ;
20
20
useEffect ( function callApi ( ) {
21
+ //1. Imagine that we are calling an api to get todos
21
22
fetchTodosFromApi ( ) . then ( list => setTodoList ( list ) ) ;
22
23
} , [ ] ) ;
23
24
25
+ //2. And we have a state for 2 counter
24
26
const [ ongoingCount , setOngoingCount ] = useState ( 0 ) ;
25
27
const [ doneCount , setDoneCount ] = useState ( 0 ) ;
26
28
29
+ // 3. But what if the setter are in a async method ?
27
30
useEffect ( function refreshCounters ( ) {
28
- setDoneCount ( todos . filter ( t => t . done ) . length ) ;
29
- setOngoingCount ( todos . filter ( t => ! t . done ) . length ) ;
31
+ ( async ( ) => {
32
+ new Promise ( resolve => setTimeout ( ( ) => {
33
+ setDoneCount ( todos . filter ( t => t . done ) . length ) ;
34
+ setOngoingCount ( todos . filter ( t => ! t . done ) . length ) ;
35
+ resolve ( ) ;
36
+ } , 1 ) ) ;
37
+ } ) ( ) ;
30
38
} , [ todos ] ) ;
31
39
40
+ //4. See how many render ?
32
41
console . log ( 'render with' , { total : todos . length , ongoingCount, doneCount} ) ;
42
+ // When I set one of the todos as "done", it re-renders 3 times
43
+ // render with { total: 5, ongoingCount: 5, doneCount: 0 } ==> when setTodoList is called
44
+ // render with { total: 5, ongoingCount: 5, doneCount: 1 } ==> when setDoneCount is called
45
+ // render with { total: 5, ongoingCount: 4, doneCount: 1 } ==> when setOngoingCount is called
46
+
47
+ //2 conclusions:
48
+ // - We still have too many render!
49
+ // - Once you are outside the "useEffect" thread, you have as many render as "setter"
33
50
34
51
const addEmptyTodo = ( ) => setTodoList ( [ createTodo ( 'Relax! Edition will come...' , false ) , ...todos ] ) ;
35
52
const markAsDone = ( index ) => setTodoList ( [ ...todos . slice ( 0 , index ) , {
0 commit comments