React/React Basic
Monsters-Rolodex 2-4 | destructuring | 끝
CodeMia
2022. 5. 31. 03:36
props 자리에 바로 destructring할 수 있다.

card-list.jsx 파일

props를 생략하고 바로 filteredMonsters만 보이게 할 것이다.

자바스크립트 { } 를 써서 filteredMonsters를 argument 자리에 바로 넣어준다.

return도 삭제한다.

import Card from '../card/card';
import './card-list.css';
const CardList = ({ filteredMonsters }) =>
<div className='card-list'>
{filteredMonsters.map((monster) => {
return (
<Card
monster={monster}
/>
)
})}
</div>
export default CardList;
search-box.jsx 정리

import './search-box.css';
const SearchBox = ({ className, placeholder, onChangeHandler }) =>
<div>
<input
className={`search-box ${className}`}
placeholder={placeholder}
onChange={onChangeHandler}
/>
</div>
export default SearchBox;
card.jsx 정리

한 단계 더 가서 id, name, email을 monster 옆에 바로 정의해서 줄일 수 있다.

import './card.css';
const Card = ({ monster: { id, name, email } }) => {
return (
<div key={id} className='card-container'>
<img
alt={`monster ${name}`}
/>
<h1>{name}</h1>
<p>{email}</p>
</div>
)
}
export default Card;

import { useState, useEffect } from 'react';
import './App.css';
import SearchBox from './components/search-box/search-box';
import CardList from './components/card-list/card-list';
const App = () => {
const [searchField, setSearchField] = useState('');
const [monsters, setMonsters] = useState([]);
const [filteredMonsters, setFilterMonsters] = useState(monsters);
useEffect(() => {
.then((response) => response.json())
.then((users) => setMonsters(users));
}, []);
useEffect(() => {
const newFilteredMonsters = monsters.filter((monster) => {
return monster.name.toLocaleLowerCase().includes(searchField);
});
setFilterMonsters(newFilteredMonsters)
}, [monsters, searchField])
const onSearchChange = (event) => {
const searchFieldString = event.target.value.toLocaleLowerCase();
setSearchField(searchFieldString);
}
return (
<div>
<h1 className='app-title'>Monsters Rolodex</h1>
<SearchBox
className='monsters-search-box'
placeholder='Search Monsters'
onChangeHandler={onSearchChange}
/>
<CardList
filteredMonsters={filteredMonsters}
/>
</div>
)
}
export default App;
App.css

body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: linear-gradient(to left,
rgb(248, 217, 191) 0%,
rgb(250, 250, 197) 100%);
text-align: center;
}
.app-title {
margin-top: 75px;
margin-bottom: 50px;
font-size: 7rem;
color: rgb(23, 133, 152);
font-family: 'Bigelow Rules'
}
card-list.css

.card-list {
width: 85vw;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 20px;
}
search-box.css

.search-box {
-webkit-appearance: none;
border: none;
outline: none;
padding: 10px;
width: 300px;
line-height: 30px;
margin-bottom: 30px;
font-size: large;
}
card.css

.card-container {
display: flex;
flex-direction: column;
background-color: rgb(221, 221, 153);
border: 1px solid rgb(172, 171, 171);
border-radius: 5px;
padding: 25px;
cursor: pointer;
-moz-osx-font-smoothing: grayscale;
backface-visibility: hidden;
transform: translateZ(0);
transition: transform 0.25s ease-out;
}
.card-container:hover {
transform: scale(1.05);
}