自定义挂钩无法按预期方式获取数据

时间:2020-10-08 21:35:40

标签: reactjs react-hooks

这是有关同一通用代码的相关帖子的后续内容。我创建了一个自定义钩子useLUGet,该钩子只是用作一些fetch / axios调用的包装。我遵循了(主要是)this repo,它本身可以正常工作,因为那里的App.js通过onSubmit事件触发了调用。就我而言,我只想在页面加载时加载一个下拉列表。自定义钩子似乎并没有触发,我不确定如何在不将useEffect(()=>{...}, [])放入空数组的情况下执行此操作,这违反了魔术钩子规则。我已经确认API端点正在运行并具有结果。我的代码中仅有的警告与未使用的声明有关。

这是我代码的胆量(自从我发表其他相关文章以来,内容有所更新)。

App.js:

import React from "react";
//import logo from "./logo.svg";
import "./App.css";
//import SearchForm from "./searchForm";
import AssetTypes from "./controls/AssetTypes";
import { GlobalProvider } from "./context/GlobalState";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

function App() {
  return (
    <div className="App">
      Home
      <AssetTypes></AssetTypes>
      {/* <GlobalProvider>
        <Router>
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/assetTypes" component={AssetTypes} />
          </Switch>
        </Router>
      </GlobalProvider> */}
    </div>
  );
}

export default App;

AssetTypes.js

import React from "react";
import { NativeSelect } from "@material-ui/core";

import { useLUGet } from "../services/Http";

function AssetTypes() {
  let path = `/AssetTypes?organizationId=999`;
  console.log("path: " & path);

  console.log("before useLUGet");
  const { status, data, error } = useLUGet(path);  // ***THIS IS THE STICKING POINT***
  console.log(JSON.stringify(data));
  console.log("after useLUGet");

  return (
    <>
      <h1>Asset Types</h1>

      <NativeSelect>
        <option>stuff</option>
        {data &&
          data.map((item) => (
            <option value={item.assetTypeId}>
              {item.assetCategory} - {item.assetTypeName}
            </option>
          ))}
      </NativeSelect>
    </>
  );
}

export default AssetTypes;

Http.js

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

const API_URL_BASE = "https://localhost:5001/api";

// Example usage:
// {status === 'idle' && (<div> Let's get started by searching for an article! </div>)}
// {status === 'error' && <div>{error}</div>}
// {status === 'fetching' && <div className="loading"></div>}
// {status === 'fetched' && (<>Do something with {data} object</>)

export const useLUGet = (path) => {
  console.log("in useLUGet");
  console.log("path: " & path);
  console.log("API_URL_BASE: " & API_URL_BASE);
  // const cache = useRef({});

  const url =
    API_URL_BASE &
    "/" &
    (path && path.substring(0, 1) === "/" ? path.substring(1) : path);

  console.log("url: " & url);

  const initialState = {
    status: "idle",
    error: null,
    data: [],
  };

  console.log("initial state: *** " & JSON.stringify(initialState));

  const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case "FETCHING":
        return { ...initialState, status: "fetching" };
      case "FETCHED":
        return { ...initialState, status: "fetched", data: action.payload };
      case "FETCH_ERROR":
        return { ...initialState, status: "error", error: action.payload };
      default:
        return state;
    }
  }, initialState);

  useEffect(() => {
    let cancelRequest = false;
    console.log("url: " & url);
    if (!url) return;

    const fetchData = async () => {
      dispatch({ type: "FETCHING" });
      //if (cache.current[url]) {
      //  const data = cache.current[url];
      //  dispatch({ type: "FETCHED", payload: data });
      //} else {
      try {
        const response = await fetch(url);
        const data = await response.json();
        //cache.current[url] = data;
        if (cancelRequest) return;
        dispatch({ type: "FETCHED", payload: data });
      } catch (error) {
        if (cancelRequest) return;
        dispatch({ type: "FETCH_ERROR", payload: error.message });
      }
      //}
    };

    fetchData();

    return function cleanup() {
      cancelRequest = true;
    };
  }, [url, path]);

  return state;
};

控制台输出:

[HMR] Waiting for update signal from WDS...
AssetTypes.js:8 0
AssetTypes.js:10 before useLUGet
Http.js:12 in useLUGet
Http.js:13 0
Http.js:14 0
Http.js:22 0
Http.js:30 0
AssetTypes.js:13 []
AssetTypes.js:14 after useLUGet
AssetTypes.js:8 0
AssetTypes.js:10 before useLUGet
Http.js:12 in useLUGet
Http.js:13 0
Http.js:14 0
Http.js:22 0
Http.js:30 0
AssetTypes.js:13 []
AssetTypes.js:14 after useLUGet
Http.js:47 0

0 个答案:

没有答案