In this example we going to fetch todos via useEffect
and fetch
for TodoList component.
TodoList.tsx
import { useEffect, useState } from 'react';
import { Todo } from '../types';
const TodoList = () => {
// Setting states
const [isLoaded, setIsLoaded] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [todos, setTodos] = useState<Todo[]>([]);
useEffect(() => {
// For axios need to use cancelToken function provided by axios
const controller = new AbortController();
// Aborts a DOM request before it has completed. For example
// switching pages or changing component
const signal = controller.signal;
// signal should be provided to fetch options
fetch('https://jsonplaceholder.typicode.com/todos', { signal })
.then((response) => response.json())
.then((body) => {
setErrorMessage('');
setTodos([...body]);
setIsLoaded(true);
})
.catch((error) => {
if (error.name !== 'AbortError') {
setErrorMessage('Unable to load todos');
console.error(error);
}
setIsLoaded(true);
});
return () => controller.abort();
}, []);
// Getting 10 todos
const slicedTodos = todos.slice(0, 10).map((todo) => {
return (
<div key={todo.id} className="flex justify-between">
<div>{todo.title}</div>
<div>{todo.completed ? 'Completed' : 'Not Completed'}</div>
</div>
);
});
return (
<div className="flex flex-col">
// Show error message if not empty
{errorMessage !== '' && <div>{errorMessage}</div>}
// Show todos if they loaded and no error
{isLoaded && errorMessage === "" ? slicedTodos : <div>Loading...</div>}
</div>
);
};
export default TodoList;
App.tsx
import './App.css';
import TodoList from './components/TodoList';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
Code example: https://github.com/DarthRevanXX/react-fetch-example
Top comments (0)