这是有关同一通用代码的相关帖子的后续内容。我创建了一个自定义钩子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