javascript - react Hook useEffect 在按钮单击时获取数据( typescript )

标签 javascript reactjs typescript react-hooks use-effect

我有一个组件,我想使用 react hook useEffect 在按钮单击时获取 isbn 数据,执行 get在路上${basicUrl}/editorials/${isbn} ,所以我写了这个组件:

import React, { Fragment, useState } from "react";
import "./Home.css";
import { V3_BASIC_URL } from "../../constants/endpoints";
import { useDataApi } from "../../store/effects/dataEffects";

import SearchIsbnElement from "../../components/SearchIsbnElement/SearchIsbnElement";
import IsbnPanelElement from "../../components/IsbnPanelElement/IsbnPanelElement";

function Home() {
  const [query, setQuery] = useState<string>("9788808677853");
  const [isValid, setIsValid] = useState<boolean>(true);

  const url = `${V3_BASIC_URL(
    process.env.REACT_APP_API_ENV
  )}/editorials/${query}`;
  const [{ isbn, isLoading, isError }, doFetch] = useDataApi(url, {
    isLoading: false,
    isError: false,
    isbn: undefined,
  });

  const buttonCallback = () => {
    doFetch(url);
  };
  const isbnRegexp = /^97\d{11}$/
  const validateQuery = (query: string): boolean => isbnRegexp.test(query)

  const inputCallback = (query: string) => {
    setQuery(query)
    setIsValid(validateQuery(query));
  };

  return (
    <div id="isbn-panel-home" className="Home">
      <SearchIsbnElement
        inputCallback={inputCallback}
        buttonCallback={buttonCallback}
        query={query}
        isValid={isValid}
      ></SearchIsbnElement>
      {isError && <div>Il servizio al momento non è disponibile, riprova più tardi</div>}
      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        !isError && 
        <Fragment>
          <IsbnPanelElement isbn={isbn}></IsbnPanelElement> 
          <p>{isbn?.scheda_volume == null && 'isbn non trovato'}</p>
        </Fragment>
      )}
    </div>
  );
}

export default Home;

useDataApi函数使用钩子(Hook) useEffect 并返回 statesetUrl在 isbn 值更改时设置新 url 的操作。这是useDataApi文件:

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

import {
  dataFetchFailure,
  dataFetchInit,
  dataFetchSuccess,
} from "../actions/dataActions";
import { dataFetchReducer, ISBNState } from "../reducers/dataReducers";
import { get } from "../../tools/request";

type InitialState = {
  isLoading: boolean,
  isError: boolean,
  isbn: undefined,
}

export const useDataApi = (initialUrl: string, initialData: InitialState) : [ISBNState, (value: string) => void]  => {
  const [url, setUrl] = useState(initialUrl);

  const [state, dispatch] = useReducer(dataFetchReducer, initialData);

  useEffect(() => {
    let didCancel: boolean = false;

    const fetchData = async (): Promise<any> => {
      dispatch(dataFetchInit());
      const options = {
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json'
        },
        auth: {
          username: `${process.env.REACT_APP_API_AUTH_USER}`,
          password: `${process.env.REACT_APP_API_AUTH_PWD}`
        }
      }
      try {
        const {data} = await get(url, options);
        if (!didCancel) {
          dispatch(dataFetchSuccess(data));
        }
      } catch (error) {
        if (!didCancel) {
          dispatch(dataFetchFailure(error));
        }
      }
    };

    fetchData();

    return () => {
      didCancel = true;
    };
  }, [url]);

  return [state, setUrl];
};

使用此代码获取在页面加载时开始,但我只想在单击按钮时获取数据。我该怎么做?

最佳答案

useEffect() 是一个钩子(Hook),通过不同的生命周期方法来操作组件。为了在 onClick 上执行某些操作,您需要为此创建一个方法:

const fetchData = async (): Promise<any> => {
  dispatch(dataFetchInit());
  const options = {
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json'
    },
    auth: {
      username: `${process.env.REACT_APP_API_AUTH_USER}`,
      password: `${process.env.REACT_APP_API_AUTH_PWD}`
    }
  }
  try {
    const {data} = await get(url, options);
    if (!didCancel) {
      dispatch(dataFetchSuccess(data));
    }
  } catch (error) {
    if (!didCancel) {
      dispatch(dataFetchFailure(error));
    }
  }
};

只要这样做,你就会没事的

编辑:新版useDataApi

export const useDataApi = (
  url: string,
  initialData: InitialState
): [ISBNState, (value: string) => void] => {
  const [state, dispatch] = useReducer(dataFetchReducer, initialData);

  const fetchData = useCallback(async (): Promise<any> => {
    dispatch(dataFetchInit());
    const options = {
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      auth: {
        username: `${process.env.REACT_APP_API_AUTH_USER}`,
        password: `${process.env.REACT_APP_API_AUTH_PWD}`,
      },
    };
    try {
      const { data } = await get(url, options);
      dispatch(dataFetchSuccess(data));
    } catch (error) {
      dispatch(dataFetchFailure(error));
    }
  }, [url]);

  return [state, fetchData];
};

关于javascript - react Hook useEffect 在按钮单击时获取数据( typescript ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66082333/

相关文章:

javascript - 如何使用 JQuery 增加或减少 jquery slider 值?

javascript - 有没有像 "correct"这样的东西用 React hooks 和 Typescript 定义状态?

ReactJS:如何监控重新渲染过程?

typescript - 无法使用@types/d3-tip : Argument of type 'Tooltip' is not assignable

javascript - 截至2018年支持ES6(ECMAScript 2015)

typescript - Angular2通过属性将函数传递给指令

javascript - Chrome 和 Firefox 中不触发鼠标按下事件

javascript - 下载 JavaScript 返回的图像 (html2canvas)

JavaScript:如何使用 switch 语句显示时间?

javascript - 使用 AngularJS 的 Paypal Express Checkout