API : Application Programming Interface
(REST or GraphQL APIs - two different standards for how a server should expose its data)
function App() {
const [movies, setMovies] = useState([]);
// sending a HTTP request is an asynchronous task
function fetchMovieHandler() {
fetch('https://swapi.dev/api/films/');
// default method is GET
// fetch returns a promise
.then(response => {
// response object which we get has a built-in method
// which will automatically translate this JSON response body
// to a real Javascript object
retutn response.json();
// this returns a promise also
}).then(data => {
const transformedMovies = data.results.map(movieData =>
return {
id : movieData.episode_id,
title : movieData.title,
openingText : movieData.opening_crawl,
relseaseDate : movieData.release_date
};
);
setMovies(transformedMovies);
})
// .catch() ... when handling errors
}
return (
<React.Fragment>
<button onClick = {fetchMoviesHandler}>Fetch Movies</button>
</React.Fragment>
)
}
async function fetchMoviesHandler() => {
const response = await fetch('https://swapi.dev/api/films/');
const data = await response.json();
const transformedMovies = data.results.map(movieData =>
return {
id : movieData.episode_id,
title : movieData.title,
openingText : movieData.opening_crawl,
relseaseDate : movieData.release_date
};
);
setMovies(transformedMovies);
}
const movie = {
title : titleRef.current.value,
openingText : openingTextRef.current.value,
releaseDate : releaseDateRef.current.value,
}
async function addMovieHandler(movie) {
const response = await fetch('the api url',{
method : 'POST',
body : JSON.stringify(movie),
headers : {
'Content-Type' : 'application/json'}
}
});
// can also apply try-catch syntax!
const data = await response.json();
console.log(data);
}
function App() {
const [movies, setMovies] = useState([]);
⭐ const [isLoading, setIsLoading] = useState(false);
async function fetchMoviesHandler() => {
⭐ setIsLoading(true);
const response = await fetch('https://swapi.dev/api/films/');
const data = await response.json();
const transformedMovies = data.results.map(movieData =>
return {
id : movieData.episode_id,
title : movieData.title,
openingText : movieData.opening_crawl,
relseaseDate : movieData.release_date
};
);
setMovies(transformedMovies);
⭐ setIsLoading(false);
}
return (
<React.Fragment>
<section>
<button onClick = {fetchMoviesHandler}>Fetch Movies</button>
</section>
<section>
⭐ {!isLoading && movies.length > 0
&& <MoviesList movies = {movies} />}
⭐ {!isLoading && movies.length === 0
&& <p>Found no movies.</p>}
⭐ {isLoading && <p>Loading...</p>}
</section>
</React.Fragment>
)
}
function App() {
const [movies, setMovies] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
async function fetchMoviesHandler() => {
setIsLoading(true);
setError(null);
⭐ try {
// wrong api 주소
const response = await fetch('https://swapi.dev/api/film/');
// *the response also has a "status" field
// which holds the concrete response status code
// Unlike Axios, in fetch API, we have to manually throw an Error
⭐ if(!response.ok) {
throw new Error('Something went wrong!');
}
const data = await response.json();
const transformedMovies = data.results.map(movieData =>
return {
id : movieData.episode_id,
title : movieData.title,
openingText : movieData.opening_crawl,
relseaseDate : movieData.release_date
};
);
setMovies(transformedMovies);
} ⭐ catch (error) {
setError(error.message);
}
setIsLoading(false);
}
let content = <p>Found no movies.</p>;
if (movies.length > 0) {
content = <MoviesList movies = {movies} />;
}
if (error) {
content = <p>{error}</p>;
}
if (isLoading) {
content = <p>Loading...</p>;
}
return (
<React.Fragment>
<section>
<button onClick = {fetchMoviesHandler}>Fetch Movies</button>
</section>
<section>
{content}
</section>
</React.Fragment>
)
}
function App() {
const [movies, setMovies] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const fetchMoviesHandler = ✨ useCallback(async () => {
setIsLoading(true);
setError(null);
try {
const response = await fetch('https://swapi.dev/api/films/');
if(!response.ok) {
throw new Error('Something went wrong!');
}
const data = await response.json();
const transformedMovies = data.results.map(movieData =>
return {
id : movieData.episode_id,
title : movieData.title,
openingText : movieData.opening_crawl,
relseaseDate : movieData.release_date
};
);
setMovies(transformedMovies);
} catch (error) {
setError(error.message);
}
setIsLoading(false);
}, []);
// should put all things that useEffect function is dependent of
// here, it is fetchMovieHandler
// the function could change when we use external state in the function
// but the function will change every time the App component re-renders
// because it is a reference type(object)
// and this process will lead to an infinite loop
// ✨-> use useCallback
⭐ useEffect(() => {
fetchMovieHandler();
}, [fetchMovieHandler]);
// since in the useEffect function it cannot return a promise
// (cannot use async/await in the useEffect function directly)
// , indirectly call a function which contains async/awiat function
let content = <p>Found no movies.</p>;
if (movies.length > 0) {
content = <MoviesList movies = {movies} />;
}
if (error) {
content = <p>{error}</p>;
}
if (isLoading) {
content = <p>Loading...</p>;
}
return (
<React.Fragment>
<section>
<button onClick = {fetchMoviesHandler}>Fetch Movies</button>
</section>
<section>
{content}
</section>
</React.Fragment>
)
}