✅ 간단한 레이아웃 생각해보기
✅ usehistory
✅ useEffect , deps
✅ useParams
---Monster.js----
import React, {useState, useEffect} from 'react';
import SearchBox from './Components/SearchBox/SearchBox';
import CardList from './Components/CardList/CardList';
import './Monsters.scss';
function Monsters() {
const [monsters, setMonsters] = useState([]);
const [userInput, setUserInput] = useState('');
useEffect(() => {
getMonsters();
}, []);
// 데이터 로딩
const getMonsters = () => {
const API = 'https://jsonplaceholder.typicode.com/users';
fetch(API)
.then((res) => res.json())
.then((result) => setMonsters(result));
};
// SearchBox 에 props로 넘겨줄 handleChange 메소드 정의
const handleChange = (e) => {
setUserInput(e.target.value);
};
return (
<div className="Monsters">
<h1>컴포넌트 재사용 연습!</h1>
<SearchBox handleChange={handleChange} />
<CardList
monsters={monsters.filter((el) => {
return el.name.toLowerCase().includes(userInput.toLocaleLowerCase());
})}
/>
</div>
);
}
export default Monsters;
id
name
email
을 props전달
function CardList({monsters}) {
return (
<div className="card-list">
{monsters.map((e) => {
return <Card id={e.id} name={e.name} email={e.email} />;
})}
</div>
);
}
export default CardList;
---Card.js----
import React from 'react';
import {useHistory} from 'react-router-dom';
function Card({id, name, email}) {
let history = useHistory();
function gotoDetail() {
history.push(`/monsters/detail/${id}`);
}
return (
<div className="card-container" onClick={gotoDetail}>
<img src={`https://robohash.org/${id}?set=set2&size=180x180`}></img>
<h2> {name}</h2>
<p> {email}</p>
</div>
);
}
export default Card;
/monsters/detail/${id}
id key 값 이용https://jsonplaceholder.typicode.com/users/
의 각 해당 id으 카드데이터 업데이트 시키기
---CardDetail--
import React, {useState, useEffect} from 'react';
import {useParams, useHistory} from 'react-router-dom';
import Card from './Components/Card/Card';
import './MonsterDetail.scss';
function MonsterDetail() {
let {id} = useParams();
let history = useHistory();
let [data, setData] = useState([]);
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
.then((res) => res.json())
.then((res) => {
setData(res);
});
}, [id]);
const goToMonstersList = () => {
history.push('/');
};
const goToPrevious = () => {
history.push(`/monsters/detail/${id - 1}`);
};
const goToNext = () => {
history.push(`/monsters/detail/${+id + 1}`);
};
return (
<div className="url-parameters">
<div className="btn-wrapper">
<button onClick={goToMonstersList}>Back to Monsters List</button>
</div>
<Card id={data.id} name={data.name} email={data.email} />
<div className="btn-wrapper">
<button onClick={goToPrevious}>Previous</button>
<button onClick={goToNext}>Next</button>
</div>
</div>
);
}
export default MonsterDetail;
useParams는 Card에서 접근한 URL를 match.params 객체로 접근 할 수있다. id를 활용해서 useEffect에서 fetch로 받아온 데이터에 변수 id를 넣어준다. 즉, Card를 클릭할때마다 해당하는 Card의 id를 useParams로 받아와서 패치하면 그에 해당하는 data를 setData에 관리해준다.
componentDidUpdate(prevProps, _) {
if (prevProps.match.params.id !== this.props.match.params.id) {
this.getData();
}
}