만들면서 배우는 react : 기초 - 12
리액트 앱의 완성도를 높여보는 작업을 해보자!!!
우선, 첫번째로 랜덤으로 고양이 이미지를 받아오는 Open API를 연결할 것이다.
고양이 open API
위 링크를 통해 고양이 사진을 랜덤으로 받아오고, 글씨를 위에 적어주는 api를 연결할 것이다.
그것을 위해선 fetch를 사용해야한다.
fetch에 대해 궁금하다면 클릭
const fetchCat = async (text) => {
const OPEN_API_DOMAIN = "https://cataas.com";
const response = await fetch(`${OPEN_API_DOMAIN}/cat/says/${text}?json=true`);
const responseJson = await response.json();
return `${OPEN_API_DOMAIN}/${responseJson.url}`;
};
fetch를 쓸 때, then이 아닌 async와 await를 사용했다.
비동기 처리를 위해서는 async, awiat가 필요하다.
async, awiat에 대해 궁금하다면 클릭
open API를 이용해서 이미지를 랜덤으로 나오게 해보자!!
const App = () => {
const [counter, setCounter] = React.useState(jsonLocalStorage.getItem("counter"));
const [mainCat, setMainCat] = React.useState(React.useEffect(() => {
setInitialCat();
}, [])); // 앱 실행하자마자, 한번만 랜덤 이미지로 노출.
const [favorites, setFavorites] = React.useState(jsonLocalStorage.getItem("favorites") || []);
async function setInitialCat() { //앱 실행시, 초기 이미지 랜덤 이미지로 노출.
const newCat = await fetchCat('First Cat');
setMainCat(newCat);
}
//생략,,,
async function updateMainCat(value) {
const newCat = await fetchCat(value); //랜덤 이미지
setMainCat(newCat);// 랜덤 이미지로 이미지 변경
const nextCounter = counter + 1;
setCounter(nextCounter);
jsonLocalStorage.setItem("counter", nextCounter);
}
//생략...
};
fetchCat을 이용하여 api 통신을 통해 랜덤이미지로 받아온다
근데, 제일 처음 앱을 실행하자마자 보이는 이미지를 설정할 때에는 useEffect가 필요하다.
앱이 실행되고나서 무한대로 api통신을 하기 때문에,
useEffect를 이용해서 초기 딱 한번만 이미지를 받아올 수 있게끔 해야한다.
그리고 mainCat 초기값에 useEffect를 넣어줘서 실행되자마자 랜덤이미지로 노출되게 했다.
만약 초기값에 다른 이미지를 넣어놓고, 밑에서 useEffect를 이용해 랜덤이미지로 노출되게 하면,
시간차가 발생된다..ㅠ_ㅜ
useEffect에 대해 궁금하다면 클릭
그 다음에는 이제 하트와 관련된 동작을 수정해보자.
하트를 누르면, 하트 아이콘에 색이 들어가게 할 예정이다.
그리고 추가로 강의에는 없었지만 아쉬운 부분이 있어 그 부분도 보완했다.
바로, 하트를 이미 누른 이미지는 하트를 또 누르면 즐겨찾기 부분에서 이미지가 삭제되게 하는 것이다..
그럼 시작해보자!
const MainCard = ({ img, onHeartClick, alredyFav }) => {
const heartIcon = alredyFav ? "💖" : "🤍"; // 즐겨찾기에 이미지가 있는지 여부에 따라 하트 아이콘 바뀜
return (
<div className="main-card">
<img src={img} alt="고양이" width="400" />
<button onClick={onHeartClick}>{heartIcon}</button> //하트아이콘 노출
</div>
);
};
const App = () => {
//생략..
const [favorites, setFavorites] = React.useState(jsonLocalStorage.getItem("favorites") || []);
const alredyFav = favorites.includes(mainCat); // 즐겨찾기에 이미지가 있는지 확인
//생략,,,
}
function handleHeartClick() {
const nextFav = alredyFav ? [...favorites].filter((element) => element !== mainCat) : [...favorites, mainCat] //삼항연산자를 이용해서 nextFav에 이미지를 삭제하거나, 이미지를 추가함
setFavorites(nextFav);
jsonLocalStorage.setItem("favorites", nextFav);
}
return (
<div>
<Title>{title}</Title>
<Form updateMainCat={updateMainCat} />
<MainCard img={mainCat} onHeartClick={handleHeartClick} alredyFav={alredyFav} /> //alreadyFav를 prop으로 넘김..
<Favorites favorites={favorites} />
</div>
);
};
이렇게 하면 하트를 누르는 것에 따라 동작이 바뀌는 것을 확인할 수 있다~!!
점점 앱의 완성도가 올라가고 있어서 하는 동안 뭔가 뿌듯했다 ㅎㅎ
그리고 뭔가 아쉬운 부분들을 찾아내서 스스로 동작을 추가하거나 고치는 것도 재미있당>_<