I am trying to convert a useReducer hooks to TypeScript, It's working fine as useReducer hooks, however not in TypeScript.
Here is my code,
import * as React from "react";
const JOKE_URL = "https://icanhazdadjoke.com/";
const initialState = { data: null, error: null, loading: true };
type ACTIONTYPE =
| { type: "fetch" }
| { type: "data"; data: object }
| {type: "error"};
function fetchReducer(state: typeof initialState, action: ACTIONTYPE) {
switch (action.type) {
case 'fetch':
return {
...state,
loading: true,
}
case 'data':
return {
...state,
data: action.data,
error: null,
loading: false,
}
case 'error':
return {
...state,
error: 'Error fetching data. Try again',
loading: false,
}
default:
return state;
}
}
function useFetch (url: string) {
const [state, dispatch] = React.useReducer(
fetchReducer,
{ data: null, error: null, loading: true }
)
React.useEffect(() => {
dispatch({ type: 'fetch' })
fetch(url, {
headers: {
accept: "application/json"
}
})
.then((res) => res.json())
.then((data) => dispatch({ type: 'data', data }))
.catch((e) => {
console.warn(e.message)
dispatch({ type: 'error' })
})
}, [url])
return {
loading: state.loading,
data: state.data,
error: state.error
}
}
export default function App() {
const { loading, data, error } = useFetch(JOKE_URL);
console.log(data);
if (loading === true) {
return <p>Loading</p>
}
if (error) {
return (
<React.Fragment>
<p>{error}</p>
</React.Fragment>
)
}
return (
<div>
<h1>{data.joke}</h1>
</div>
);
}
I am getting some errors like: -> Argument of type '(state: { data: null; error: null; loading: boolean; }, action: ACTIONTYPE) => { data: null; error: null; loading: boolean; } | { data: object; error: null; loading: boolean; } | { error: string; loading: boolean; data: null; }' is not assignable to parameter of type 'ReducerWithoutAction'. TS2769 -> Expected 0 arguments, but got 1. TS2554