React useAsync-Hook
index.html
und script.js
wurden bereits in der VM bereitgestellt. Im Allgemeinen müssen Sie nur Code in script.js
und style.css
hinzufügen.
Dieser Code erstellt einen benutzerdefinierten Hook, der asynchrone Aufrufe behandelt. Er akzeptiert eine Handler-Funktion, fn
, und gibt ein Objekt zurück, das die Eigenschaften von state
(value
, error
und loading
) und eine asynchrone run
-Funktion enthält. Die run
-Funktion führt die bereitgestellte Callback-Funktion fn
aus und verwendet dabei dispatch
, um state
sofern notwendig zu aktualisieren.
const useAsync = (fn) => {
const initialState = { loading: false, error: null, value: null };
const stateReducer = (state, action) => {
switch (action.type) {
case "start":
return { loading: true, error: null, value: null };
case "finish":
return { loading: false, error: null, value: action.value };
case "error":
return { loading: false, error: action.error, value: null };
default:
return state;
}
};
const [state, dispatch] = React.useReducer(stateReducer, initialState);
const run = async (args = null) => {
try {
dispatch({ type: "start" });
const value = await fn(args);
dispatch({ type: "finish", value });
} catch (error) {
dispatch({ type: "error", error });
}
};
return { ...state, run };
};
const RandomImage = (props) => {
const imgFetch = useAsync((url) =>
fetch(url).then((response) => response.json())
);
return (
<div>
<button
onClick={() => imgFetch.run("https://dog.ceo/api/breeds/image/random")}
disabled={imgFetch.loading}
>
Load image
</button>
<br />
{imgFetch.loading && <div>Loading...</div>}
{imgFetch.error && <div>Error {imgFetch.error}</div>}
{imgFetch.value && (
<img
src={imgFetch.value.message}
alt="avatar"
width={400}
height="auto"
/>
)}
</div>
);
};
ReactDOM.createRoot(document.getElementById("root")).render(<RandomImage />);
Bitte klicken Sie auf 'Go Live' in der unteren rechten Ecke, um den Webdienst auf Port 8080 auszuführen. Anschließend können Sie die Registerkarte Web 8080 aktualisieren, um die Webseite anzuschauen.