[Suggestion]: Make useEffectEvent be usable by default in the challenges or add a new note for useRef's alternative
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- JavaScript
- Estrellas
- 11.8k
- Forks
- 7.9k
- Merge medio
- 1 d 11 h
- PR fusionados (30 d)
- 11
Descripción
Summary
Make useEffectEvent be usable by default in Separating Events from Effects' challenges, or add a new note for useRef's alternative.
Page
https://react.dev/learn/separating-events-from-effects
Details
I attempted to solve the first challenge in Separating Events from Effects with useEffectEvent. First, following the previous example, I imported that function with this line:
import { experimental_useEffectEvent as useEffectEvent } from 'react';
Then, I used it with these lines:
const updateCount = useEffectEvent(() => {
setCount(c => c + increment);
});
However, this error was shown up:
Runtime Error
App.js: _react.experimental_useEffectEvent is not a function (8:37)
5 | const [count, setCount] = useState(0);
6 | const [increment, setIncrement] = useState(1);
7 |
> 8 | const updateCount = useEffectEvent(() => {
^
9 | setCount(c => c + increment);
10 | });
11 |
Therefore, by default, I can't use useEffectEvent for that exercise. I wrote "by default" because maybe it can be used by opening it in CodeSandbox. It looks like an extra effort for me, so I haven't tried it yet.
One of the solution I found for this challenge is using useRef. I think, the key for this challenge is how to avoid passing reactive elements to the Effect. Because useRef somehow can be treated as local variable which can be changed outside of render, and the interval itself is in-between render, I think it's safe to use. I need to make a Ref consistent with increment state. So, I modified each callback function of the increment buttons.
Here is my solution:
import { useState, useEffect, useRef } from 'react';
export default function Timer() {
const [count, setCount] = useState(0);
const [increment, setIncrement] = useState(1);
const incrementRef = useRef(1);
function decreaseIncrement() {
const prevIncrement = increment;
const newIncrement = prevIncrement - 1;
setIncrement(newIncrement);
incrementRef.current = newIncrement;
}
function increaseIncrement() {
const prevIncrement = increment;
const newIncrement = prevIncrement + 1;
setIncrement(newIncrement);
incrementRef.current = newIncrement;
}
useEffect(() => {
const id = setInterval(() => {
const localIncrement = incrementRef.current;
setCount(c => c + localIncrement);
}, 1000);
return () => {
clearInterval(id);
};
}, []);
return (
<>
<h1>
Counter: {count}
<button onClick={() => setCount(0)}>Reset</button>
</h1>
<hr />
<p>
Every second, increment by:
<button disabled={increment === 0} onClick={() => {
decreaseIncrement()
}}>–</button>
<b>{increment}</b>
<button onClick={() => {
increaseIncrement();
}}>+</button>
</p>
</>
);
}
It would be better if the useRef's alternative is included as a new note in Separating Events from Effects section.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con la página Separating Events from Effects y reproduce el primer challenge usando la importación documentada de useEffectEvent. Determina si el entorno del challenge debería admitir esa API o si la página debería documentar la alternativa useRef; se considera terminado cuando el enfoque elegido está disponible o se explica claramente en el challenge y en las indicaciones relacionadas.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- javascript, react
- Área
- documentation
- Tipo de issue
- Documentación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 38/100