Обязательный запуск асинхронного запроса с перехватчиками React - PullRequest
1 голос
/ 17 апреля 2019

У меня возникают проблемы с выбором способа вызова вызова API обязательно , например, при нажатии кнопки.
Я не уверен, каков правильный подход с крючками, потому что, кажется, существует более одного метода, но я не понимаю, какой подход является «лучшим» и возможные последствия.

Я нашел следующие примеры, которые достаточно просты и делают то, что я хочу:

Использование useEffect () со значением триггера

function SomeFunctionComponent() {
  const [fakeData, setFakeData] = useState(0);
  const [trigger, setTrigger] = useState(false);

  async function fetchData() {
    if (!trigger) return;

    const newData = await someAPI.fetch();

    setTrigger(false);
    setFakeData(newData);
  }

  useEffect(() => {
    fetchData();
  }, [trigger]);

  return (
    <React.Fragment>
      <p>{fakeData}</p>
      <button onClick={() => setTrigger(!trigger)}>Refresh</button>
    </React.Fragment>
  );
}

Пример

Просто вызовите API и затем setState ()

function SomeFunctionComponent() {
  const [fakeData, setFakeData] = useState(0);

  async function fetchData() {
    const newData = await someAPI.fetch();

    setFakeData(newData);
  }

  return (
    <React.Fragment>
      <p>{fakeData}</p>
      <button onClick={fetchData}>Refresh</button>
    </React.Fragment>
  );
}

Пример

Существуют также другие подходы, использующие useCallback (), но, насколько я понял, они полезны, чтобы избежать повторного рендеринга дочерних компонентов при передаче обратных вызовов, и эквивалентны второму примеру.

Я думаю, что подход useEffect полезен только тогда, когда что-то должно запускаться при монтировании компонентов и программно, но наличие того, что по сути является фиктивным значением для запуска побочного эффекта, выглядит многословно.
Просто вызов функции выглядит прагматично и достаточно просто, но я не уверен, разрешено ли компоненту функции выполнять побочные эффекты во время рендеринга.

Какой подход является наиболее идиоматичным и правильным, чтобы императивные вызовы с использованием хуков в React?

1 Ответ

3 голосов
/ 17 апреля 2019

Первое, что я делаю, когда пытаюсь найти лучший способ написать что-то, - посмотреть, как бы я хотел это использовать. В вашем случае этот код:

    <React.Fragment>
      <p>{fakeData}</p>
      <button onClick={fetchData}>Refresh</button>
    </React.Fragment>

кажется самым простым и понятным. Что-то вроде <button onClick={() => setTrigger(!trigger)}>Refresh</button> скрывает ваше намерение с деталями реализации.

Что касается вашего вопроса, отметьте, что «я не уверен, разрешено ли компоненту функции выполнять побочные эффекты во время рендеринга». во время рендеринга компонент функции не создает побочных эффектов, поскольку при нажатии на кнопку рендеринг не происходит. Только когда вы звоните setFakeData, рендеринг действительно происходит. В этом отношении нет практической разницы между реализацией 1 и реализацией 2, поскольку в обоих случаях только при вызове setFakeData происходит рендеринг.

Когда вы начнете обобщать это, вы, вероятно, захотите изменить эту реализацию все вместе на что-то еще более общее, что-то вроде:

  function useApi(action,initial){
    const [data,setData] = useState({
      value:initial,
      loading:false
    });

    async function doLoad(...args){
        setData({
           value:data.value,
           loading:true
        });
        const res = await action(...args);
        setData({
            value:res,
            loading:false
        })
    }
    return [data.value,doLoad,data.loading]
  }
  function SomeFunctionComponent() {
    const [data,doLoad,loading] = useApi(someAPI.fetch,0)
    return <React.Fragment>
      <p>{data}</p>
      <button onClick={doLoad}>Refresh</button>
    </React.Fragment>
  }
...