Неправильно ли получить API без использования useEffect Hook? - PullRequest
4 голосов
/ 20 мая 2019

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

import React, { useState, useEffect } from "react";

const fetchTheApi = () =>
  new Promise(res => setTimeout(() => res({ title: "Title fetched" }), 3000));

const UseEffectlessComponent = () => {
  const [data, setData] = useState();
  !data && fetchTheApi().then(newData => setData(newData));
  return <h1>{data ? data.title : "No title"}</h1>;
};

const UseEffectComponent = () => {
  const [data, setData] = useState();
  useEffect(() => {
    fetchTheApi().then(newData => setData(newData));
  }, []);
  return <h1>{data ? data.title : "No title"}</h1>;
};

const MyComponent = () => (
  <div>
    <UseEffectlessComponent />
    <UseEffectComponent />
  </div>
);

Редактировать на основе ответов:

Я изменил код для рендеринга, например:

import React, { useState, useEffect } from 'react';

const fetchTheApi = (origin) => {
    console.log('called from ' + origin);
    return new Promise((res) =>
        setTimeout(() => res({ title: 'Title fetched' }), 3000)
    );
};

const UseEffectlessComponent = () => {
    const [data, setData] = useState();
    !data &&
        fetchTheApi('UseEffectlessComponent').then((newData) => setData(newData));
    return <h1>{data ? data.title : 'No title'}</h1>;
};

const UseEffectComponent = () => {
    const [data, setData] = useState();
    useEffect(() => {
        fetchTheApi('UseEffectComponent').then((newData) => setData(newData));
    }, []);
    return <h1>{data ? data.title : 'No title'}</h1>;
};

const MyComponent = () => {
    const [counter, setCounter] = useState(0);
    counter < 3 && setTimeout(() => setCounter(counter + 1), 1000);
    return (
        <div>
            <p>counter is: {counter}</p>
            <UseEffectlessComponent />
            <UseEffectComponent />
        </div>
    );
};

В консоли Iполучил:

called from UseEffectlessComponent called from UseEffectComponent called from UseEffectlessComponent called from UseEffectlessComponent called from UseEffectlessComponent

Итак, я наконец-то нашел пользу для этого подхода.У меня есть код для изменения ... Большое спасибо за ответы!

Ответы [ 3 ]

3 голосов
/ 20 мая 2019

Как вы написали, это работает, вроде.Вы говорите: «Если выборка не удалась, а компонент перерисовался, попробуйте еще раз, иначе нет».Лично я считаю, что это ненадежная система - в зависимости от повторного рендеринга попытаться еще раз и может легко привести к непреднамеренным побочным эффектам:

  • Что если ваши данные неверны?Что делать, если это не удается (что вы не справились).В этом случае он будет пытаться повторно извлечь.

  • Что делать, если родительский рендеринг выполняется 3 раза подряд (очень распространенная ситуация).В этом случае ваша выборка произойдет 3 раза до завершения первой выборки.

Таким образом, с учетом этого вам на самом деле нужны более тщательные проверки, чтобы убедиться, что ваш код не имеет неожиданных последствий.не используя useEffect.Кроме того, если ваша выборка требует повторной выборки изменений реквизита, ваше решение также не работает.

2 голосов
/ 20 мая 2019

Прямо сейчас, если ваш компонент выполняет рендеринг до того, как он установил данные, он попытается извлечь данные снова, что приведет к множественным выборкам. Учитывая, что вы хотите получать данные только один раз, а не случайно несколько раз, было бы лучше поместить их в useEffect.

0 голосов
/ 20 мая 2019

Вы должны использовать useEffect, потому что вы делаете анти-шаблон. С сайта реакции вы можете ясно увидеть, почему useEffect существует:

Выборка данных, настройка подписки и изменение вручную Все компоненты DOM в React являются примерами побочных эффектов. Или Вы не привыкли называть эти операции «побочными эффектами» (или просто «Эффекты»), вы, вероятно, выполняли их ранее в своих компонентах. https://reactjs.org/docs/hooks-effect.html

Компоненты React - это просто функции, некоторые реквизиты и несколько jsx. Если вы хотите иметь побочный эффект, вы не должны иметь его непосредственно в вашем компоненте. Это должно быть в методе жизненного цикла.

Представьте, что проверка вашего состояния (! Data) была сложной, зацикливаясь на массивах и т.д. Это оказало бы большее влияние на производительность. Но useEffect будет более производительным, и вы даже можете использовать второй аргумент для своего рода «кэширования» результатов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...