Реагировать на возврат функции высшего порядка - PullRequest
1 голос
/ 07 мая 2020

В настоящее время у меня есть настраиваемая ловушка выборки данных, написанная на javascript, и она работает

import {useState, useEffect} from 'react';

const useApi = apiName => id => {
  const [response, setResponse] = useState();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const fetching = async () => {
    setLoading(true);
    const data = await fetch(`/api/${apiName}${id ? `/${id}` : ""}`)
      .then((x) => x.json())
      .catch((error) => setError(error));

    setResponse(data);
    setLoading(false);
  };

  useEffect(() => {
    fetching();
  }, [id]);

  return { response, loading, error };
};

Затем я могу использовать pass в том API, который я хочу вызвать, чтобы получить ловушку. Например:

const useCustomer = useApi("customer")
const useHello = useApi("hello")
.....
const {response, loading, error} = useCustomer("id_1")

Работает нормально.

Затем я пытаюсь преобразовать в машинописный текст

const useApi = (apiName:string) => (id?:string) => {
  const [response, setResponse] = useState({})
.......
}

, и eslint жалуется, что

React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function

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

const useApi = (apiName:string, id?:string) => {} 

или отключить eslint (react-hooks / rules-of-hooks)

Но просто любопытно, каковы потенциальные проблемы с функцией перехвата более высокого порядка, поскольку она фактически возвращает ответ.

Спасибо

1 Ответ

0 голосов
/ 07 мая 2020

Когда вы называете свою функцию с помощью хуков prefix, eslint думает об этом как о пользовательском хуке в соответствии с общим соглашением. Теперь он реализует useState во вложенной функции, поэтому выдает ошибку

Лучший способ написать приведенный выше код - не использовать функцию каррирования, а передать apiName в качестве параметра напрямую

const useApi = (apiName, id) => {
  const [response, setResponse] = useState();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const fetching = async () => {
    setLoading(true);
    const data = await fetch(`/api/${apiName}${id ? `/${id}` : ""}`)
      .then((x) => x.json())
      .catch((error) => setError(error));

    setResponse(data);
    setLoading(false);
  };

  useEffect(() => {
    fetching();
  }, [id]);

  return { response, loading, error };
};

и используйте его как

.....

const {response, loading, error} = useApi("customer","id_1");

PS Хуки предназначены для того, чтобы быть альтернативой HO C, и нет смысла писать крючок, если вы используете его как HO C сам

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