Reputation: 10480
I took a two day React training class last week. The instructor tried to jam a weeks worth of info into two days. We slapped together a crude blackjack game in the "class" (or is that Class<T>: => () await (...p)
ha ha little Typescript joke there.) The class did not get around to covering how to access a REST API. So here I am stuck with a bunch of confusing unreadable code that I am not even sure is React or Typescript. Any whooo this is my App.tsx file:
import React, {useState} from 'react';
import './App.css';
import {fetchUser, User, UserCtx} from "./User";
import {useAsync} from "./ss-react-utils";
const AppLoaded = ({user}: {user: User}) => {
return <div className="App">
{user.userName}
</div>;
};
const AppLoading = () => {
return <div>Loading ...</div>;
};
const App: React.FC = () => { // I guess the FC stands for F*king Confusing
const [user, setUser] = useState<User | null>(null);
useAsync({
op: fetchUser,
onSuccess: setUser,
deps: []
});
if (user !== null) {
return <AppLoaded user={user} />;
} else {
return <AppLoading/>;
}
}
export default App;
Here's the ss-react-utils.tsx file:
import React, {CSSProperties, DependencyList, useEffect} from "react";
export type Op<T> = () => Promise<T>;
export type OnSuccess<T> = (data: T) => void;
export function useAsync<T>({op, onSuccess, deps}: { op: Op<T>, onSuccess: OnSuccess<T>, deps?: DependencyList }) {
useEffect(() => {
const doOp = async () => {
const data: T = await op();
onSuccess(data);
};
doOp();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
}
... some other unrelated ( I think ) code ...
when I run that code I get this ...
I would like to know how to handle the error and display the login page to the user if the REST API returns a 403 forbidden error.
And Yes I know the REST API is returning a 403 error. So please don't answer the question with you are getting a 403 error.
:)
Also I have seen a lot of answers that say use componentDidMount
but the instructor said that was the old way of doing React and he was going to teach about hooks instead. Well would like to try what the instructor was getting at before I completely give up on the "New" way to code React. And probably React all together. So please help :)
UPDATE: I am using Django Rest Framework and it is behaving as expected.
Upvotes: 0
Views: 3294
Reputation: 2351
const App: React.FC<{id}> = ({id}) => {
const op = useCallback(()=> fetchUser(id), [id]);
const { data: user, loading, error } = useFetch(op);
useEffect(()=> {
if (!error){return}
alert(error); // if wanna alert error;
}, [error]);
return (
<>
{loading && <AppLoading />}
{user && <AppLoaded user={user}/>}
{error && <pre>{error.message | error}</pre>}
</>
)
}
function useFetch<T>(op: ()=> Promise<T>){
const [loading, setLoading] = useState(false);
const [data, setData] = useState<T | null | undefined>();
const [error, setError] = useState<string | null>(null);
const id = useRef(0);
useEffect(()=> ()=> {
// on unmount
id.current = 0;
}, []);
useEffect(()=> {
const currentID = ++id.current;
setLoading(true);
op().then((data)=> {
// ignore when query changed
if (id.current !== currentID) { return; }
setData(data);
setLoading(false);
setError(null);
}, (err)=> {
if (id.current !== currentID) { return; }
setError(err.message || err);
setLoading(false);
})
}, op);
return {data, loading, error}
}
Upvotes: 1
Reputation: 484
You can handle error in this way. Here is the example:-
componentDidMount() {
fetch(URL)
.then(results => results.json())
.then(data => this.setState({ results: data }))
.catch(error=>{ //here you can handel errors
if(error.response){
alert("Error occurred");
}
});
}
Upvotes: 0
Reputation: 1233
In my last project, I have a problem with async download data from api. Then I must use something like this:
componentDidMount() {
fetch("API")
.then(res => res.json())
.then(json => {
...
this.setState({ data });
});
}
But this code is for the class component. Can you test this same code with only fetch data?
We will exclude in this way whether it is the fault of the data download itself.
Upvotes: 0