Как отправить запрос на клик React Hooks способом? - PullRequest
3 голосов
/ 12 апреля 2019

Как отправить http-запрос по нажатию кнопки с реагирующими хуками? Или, если на то пошло, как сделать любой побочный эффект при нажатии кнопки?

Что я вижу до сих пор, так это что-то вроде "косвенного":

export default = () => {
  const [sendRequest, setSendRequest] = useState(false);

  useEffect(() => {
    if(sendRequest){
       //send the request
       setSendRequest(false);
    }
  },
  [sendRequest]);

  return (
    <input type="button" disabled={sendRequest} onClick={() => setSendRequest(true)}
  );
}

Это правильный путь или есть какой-то другой паттерн?

Ответы [ 4 ]

7 голосов
/ 12 апреля 2019
export default () => {
  const [isSending, setIsSending] = useState(false)
  const sendRequest = useCallback(async () => {
    // don't send again while we are sending
    if (isSending) return
    // update state
    setIsSending(true)
    // send the actual request
    await API.sendRequest()
    // once the request is sent, update state again
    setIsSending(false)
  }, [isSending]) // update the callback if the state changes

  return (
    <input type="button" disabled={isSending} onClick={sendRequest} />
  )
}

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

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

Вам не нужен эффект для отправки запроса по нажатию кнопки, вместо этого вам нужен только метод обработчика, который вы можете оптимизировать, используя useCallback метод

const App = (props) => {
   //define you app state here
   const fetchRequest = useCallback(() => {
       // Api request here
   }, [add dependent variables here]);

  return (
    <input type="button" disabled={sendRequest} onClick={fetchRequest}
  );
}

Запрос отслеживания с использованием переменной с useEffect не является правильным шаблоном, поскольку вы можете установить состояние для вызова API с помощью useEffect, но дополнительный рендеринг из-за некоторых других изменений приведет к тому, что запрос будет зациклен

2 голосов
/ 12 апреля 2019

Вы можете определить логическое значение в состоянии, как вы сделали, и как только вы инициируете запрос, установите его на true, а когда вы получите ответ, установите его на false:

const [requestSent, setRequestSent] = useState(false);

const sendRequest = () => {
  setRequestSent(true);
  fetch().then(() => setRequestSent(false));
};

Рабочий пример

1 голос
/ 12 апреля 2019

Вы можете извлекать данные как результат некоторого изменения состояния, как вы сделали в своем вопросе, но вы также можете получать данные непосредственно в обработчике кликов, как вы привыкли в компоненте класса.

Пример

const { useState } = React;

function getData() {
  return new Promise(resolve => setTimeout(() => resolve(Math.random()), 1000))
}

function App() {
  const [data, setData] = useState(0)

  function onClick() {
    getData().then(setData)
  }

  return (
    <div>
      <button onClick={onClick}>Get data</button>
      <div>{data}</div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="root"></div>
...