reactjs / reactjs/react.dev

[Suggestion]: Make useEffectEvent be usable by default in the challenges or add a new note for useRef's alternative

Aberta
#7,605 0 comentários 1 reação 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

type: documentation
Linguagem predominante
JavaScript
Estrelas
11.8k
Forks
7.9k
Merge médio
1d 11h
PRs com merge (30d)
11

Descrição

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.

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece pela página Separating Events from Effects e reproduza o primeiro challenge usando o import documentado de useEffectEvent. Determine se o ambiente do challenge deve oferecer suporte a essa API ou se a página deve documentar a alternativa useRef; considera-se concluído quando a abordagem escolhida estiver disponível ou claramente explicada no challenge e nas orientações relacionadas.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
javascript, react
Domínio
documentation
Tipo de issue
Documentação
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
38/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.