Это продолжение связанного сообщения о том же общем коде. Я создал специальный хук useLUGet, предназначенный только для того, чтобы быть оболочкой для некоторых вызовов fetch/axios. Я следовал (в основном) этому репозиторию, который отлично работает сам по себе, потому что 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
useEffect(()=>{...}, [])
противоречит правилам магического крючка? Возможно, ознакомьтесь сuseEffect
документами. Правила линтинга для хуков — это просто общие рекомендации, чтобы избежать устаревшего состояния. - person Drew Reese   schedule 09.10.2020useLUGet
кажется правильным, я не вижу проблем и работает в этом файле codesandbox, однако я вижу, что вы выполняете какие-то странные побитовые операции И (&
). Похоже, вы хотели использовать+
для конкатенации строк, но вместо этого использовали амперсанд&
. Кажется вероятным, что вы создали неверный URL-адрес, и выборка не удалась, что вызвало некоторую проблему с условным вызовом. Можете ли вы попробовать воспроизвести свою проблему в рабочих кодах и дать ссылку здесь? - person Drew Reese   schedule 09.10.2020