티스토리 뷰
App.js
import React, { Component } from "react";
import './App.css'
import Header from "./Header";
import Cardlist from './Cardlist'
class App extends Component{
state = {
serverData : [],
flag : true,
filteredData: [],
enterSignal : true
}
// 검색하기
searchItem = (keyWord) => { // 검색어를 내려줘야한다
// e.preventDefault()
const { serverData, filteredData } = this.state
this.setState( prevState => ({
filteredData : serverData.filter(data => [data.brand, data.price, data.name, data.description].some(item =>
item.toLowerCase().includes(keyWord)))}))
console.log(filteredData)
}
// 가격별 오름차순, 내림차순 정렬하기
sortItem = () => {
const { serverData, filteredData } = this.state
const selectData = filteredData.length > 0 ? filteredData : serverData
this.setState(prevState => ({
flag: !prevState.flag,
filteredData: [...selectData].sort((a, b) =>
prevState.flag ? a.price - b.price : b.price - a.price
)
}));
}
handleState = (trans) => {
this.setState({ enterSignal : trans })
}
componentDidMount(){
const API_URL = 'http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline'
fetch(API_URL)
.then(res => res.json())
.then(data => { this.setState({ serverData: data })})
// console.log(this.state.searchResult)
}
render(){
const { serverData, filteredData, enterSignal } = this.state
// console.log(this.state.serverData, this.state.flag) // 디버깅용
return(
<>
<Header
handleClick={this.sortItem}
serverData={serverData}
searchClick={this.searchItem}
enterSignal = {this.handleState}
filteredData={filteredData}
></Header>
<main>
<Cardlist
key = {serverData.id}
products = {serverData}
filterProducts = {filteredData}
enterSignal = {this.handleState}
></Cardlist>
</main>
</>
)
}
}
export default App
Header.js
import React, { Component } from "react";
import './Header.css'
import Search from './Search.js'
import Button from "./Button";
class Header extends Component{
state = {
keyWord : ''
}
onSearch = (e) => {
const { keyWord } = this.state
const { searchClick, enterSignal } = this.props
// if (/\n/.test(e.target.value)) 검색어 중에 enter 키가 있는지 찾는 정규표현식
// console.log(e.key)
if(e.key !== 'Backspace'){
if (e.key === 'Enter' && e.target.value.length > 1){
// 검색하기
enterSignal(false)
this.setState({
keyWord : e.target.value.toLowerCase()
})
searchClick(keyWord)
}else if(e.key === 'Enter' && e.target.value.length === 1){
alert('검색어를 2자 이상 입력해주세요')
}else if(e.target.value === ''){
alert('검색어를 입력해주세요')
}else{
enterSignal(true)
this.setState({ keyWord : e.target.value })
}
}
}
render(){
const { keyWord, onSearch } = this.state
const { handleClick, searchClick, handleState, filteredData } = this.props
// console.log( keyWord)
return (
<header>
<Search
inputEnter={(e) => this.onSearch(e)}
searchWord={keyWord}
></Search>
<Button handleClick={handleClick}>가격별정렬</Button>
</header>
);
}
}
export default Header;
Search.js
import React from "react";
import './Search.css'
function Search({inputEnter,searchWord}){
// console.log(searchWord)
return(
<form action="#">
<label>
<input type='search' placeholder="검색어를 입력하세요" onKeyUp={(e)=>inputEnter(e)} defaultValue={searchWord}></input>
</label>
</form>
)
}
export default Search
Button.js
import './Button.css'
function Button({children, handleClick}){ //props
return <button className={`Button`} onClick={handleClick}>{children}</button>
}
export default Button
Cardlist.js
import React from "react";
import './Cardlist.css'
import Card from "./Card";
function Cardlist({products, filterProducts, enterSignal}){ //props
const newResults = filterProducts?.length > 0 ? filterProducts : products
return (
<div className="card-list">
{
newResults?.map(product =>
<Card
key={product.id}
brand={product.brand}
image={product.image_link}
name={product.name}
price={product.price}
description={product.description}
>
</Card>
)
}
</div>
)
}
export default Cardlist
// { reuturn } = () // 중괄호 안에 return 을 쓰는것과 ()괄호로 감싸주는것과 같은 결과가 나온다
Card.js
import React from "react";
import './Card.css'
function Card({ brand, image, name, price, description}){
return(
<>
<div className="product">
<div className="product-img">
<img src={image} alt={name}></img>
</div>
<div className="product-name"><h3>{brand}{name}({price})</h3></div>
<div className="product-description">{description}</div>
</div>
</>
)
}
export default Card
Card.css
.product{
flex: 200px;
height: 500px;
box-shadow: 1px 1px 5px 5px peru;
color: white;
background: peru;
margin: 10px;
overflow: hidden;
}
.product-img{
width: 100%;
height: 180px;
overflow: hidden;
}
.product-img img{
width: 100%;
height: 100%;
}
.product-name{
font-weight: bold;
font-size: 1.1rem;
text-align: center;
}
.product-description{
font-weight: 400;
font-size: 0.9rem;
text-align: center;
margin-top: 15px;
}
Cardlist.css
.card-list{
width: 60%;
margin: 100px auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
Header.css
header{
width: 100%;
height: 70px;
position: fixed;
left: 0;
top: 0;
right: 0;
box-shadow: 1px 1px 5px 5px darkgray;
background: white;
z-index: 1;
display: flex;
justify-content: flex-end;
align-items: center;
}
Button.css
.Button{
all: unset;
width: 100px;
height: 50px;
background: peru;
border-radius: 10px;
cursor: pointer;
color: white;
font-size: 1rem;
font-weight: bold;
text-align: center;
margin-right: 10px;
}
.Button:hover{
background-color: rgb(255, 136, 0);
opacity: 0.8;
}
'개발공부 > React' 카테고리의 다른 글
#React_map함수 내에서 JSX를 반환할 때 괄호의 차이 (0) | 2024.07.11 |
---|---|
#React 이미지 경로 문제 (0) | 2024.05.17 |
React_사이드바 만들기 (0) | 2023.09.07 |
React_삼항연산자, 배열의 객체의 속성에 접근하기 (0) | 2023.09.07 |
React_하위 컴포넌트로 props가 전달되는 과정 (0) | 2023.09.07 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- react
- 태스크큐
- null과 undefined
- 함수형코딩
- 에이블스쿨2일차
- 함수
- JSX
- universal rendering
- 조대곤교수님
- Props
- 배열내특정요소찾기
- 객체리터럴
- promise
- .finally()
- 상속
- 미들웨어위치
- .then()
- 객체속성 추가 삭제
- unexpected character
- .catch()
- 비동기
- 프로토타입 체이닝
- 문자열
- unique "key" prop.
- cors위치
- 동등비교연산자
- 머리아프다..
- 전역변수
- 대괄호표기법
- 리액트 이미지경로
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
글 보관함