오늘의 과제
- mapgoods 컴포넌트의 list 아이템중에 한개만 선택하는 것을 설정하기.
지금 문제점은 여러개가 같이 동시에 onMouse 이벤트가 작동한다.
import React, { Component } from "react";
import { Link } from 'react-router-dom';
import "./Mapgoods.scss";
// const obj = {
// 0:
// }
class Mapgoods extends Component {
constructor() {
super();
this.state = {
products : [],
btnChange: true,
display: null,
}
this.hoverOverChange = this.hoverOverChange.bind(this);
this.hoverOutChange = this.hoverOutChange.bind(this);
}
componentDidMount() {
fetch("http://localhost:3000/data/mocup.json")
.then(res => res.json())
.then(res => {
this.setState({products : res.products})
})
}
hadleChangeBtn = (e) => {
this.setState ({
btnChange : false
});
}
hoverOverChange = (e) => {
console.log(id);
this.setState({
display: true,
});
}
hoverOutChange = (e) => {
this.setState({
display : false
})
}
render() {
return (
<>
{this.state.products.map(el => (
<div onMouseOver={() => this.hoverOverChange(id)} onMouseOut={() => this.hoverOutChange(id)} className={this.state.display ?
`hoverState subcategoryProducts `: `nonehoverState subcategoryProducts`}>
<div className="subcatProductWrapper">
<div className="pictureImgLinkControl">
<Link className="pictureImgLinkTag" to="">
<div className="productPicture">
<img className="pictureImg" src={el.image} alt=""></img>
</div>
</Link>
</div>
<div className="productSizePrice">
<Link to="" >
<h5 className="productSizePriceName">{el.name}</h5>
<div className="productSizePriceInfo">
<span>{el.size}</span>
<span className="spanSlash">/</span>
<span>{el.price}</span>
</div>
</Link>
</div>
<div className="productDetailLink">
{/* <Link to=""> */}
<div className="productDetails">
<ul className="productList">
<li className="productDetailsListItem">
<div className="productDetailsTitle">{el.detail}</div>
<div className="productDetailsContent">{el.type}</div>
</li>
<li className="productDetailsListItem">
<div className="productDetailsTitle">{el.feeltitle}</div>
<div className="productDetailsContent">{el.feel}</div>
</li>
</ul>
</div>
<div onMouseOver={this.hoverOverChange.bind(this)} onMouseOut={this.hoverOutChange.bind(this)} className={this.state.display?
`hoverState productWrapper` : `nonehoverState productWrapper`} >
<button className="productCartBtn" type="button">
<div className="btnContent">
<span onClick={this.hadleChangeBtn} className={this.state.btnChange ? "btnLabel" : "noneBtnLabel"}>카트에 추가 — {el.price}</span>
<span className={this.state.btnChange ? "btnLabelAction" : "nonebtnLabelAction" }>카트에 추가됨</span>
<span className="loadingIndicatorLight"></span>
</div>
</button>
</div>
{/* </Link> */}
</div>
</div>
</div>
))}
</>
)}
}
export default Mapgoods;
해당 코드상태
activeTab으로 적용하면 되는 것 같은데, 컴포넌트 바깥에서 const obj를 설정하여 id값을 불러오려고 했으나
실패...
콜백함수를 어떻게 적용해야할지 모르겠다. (콜백함수란 일정 시점에서 호출되도록 불려지는 것을 말함)
문제점은 무엇일까???
<div onMouseOver={() => this.hoverOverChange(id)} onMouseOut={() => this.hoverOutChange(id)} className={this.state.display ?
`hoverState subcategoryProducts `: `nonehoverState subcategoryProducts`}>
뭔가 부족한데, 뭐가 문제일까??????
stacoverflow를 보기 map을 통해 모두 작동하기에 한개만 선택되는 것을 이해할 수 있게 설정해야한다고 하는데,
뭐가 적용되는 부분인지를 모르겠다.
왜냐하면 나는 prorps로 받는게 아니라 해당값을 그냥 해당 컴포넌트에서 받았기에...
차라리 싹다 엎고 그냥 props로 받아서 고치는게 나을까? 음....
해결방안.
map을 안나누었더니 결국 해당 컴포넌트 객체를 모두 한곳에서 돌려지다보니 모두 선택되는 문제때문에 결국 분리를 시작하였다.
import React, { Component } from "react";
import Nav from "../../Components/Nav/Nav";
// import Productfilternav from "../../Components/Productfilternav";
import Mapcomponent from "./Component/Mapcomponent";
import Footer from "../../Components/Footer/Footer";
import "./Maplist.scss";
class MapList extends Component {
constructor(props) {
super(props);
this.state= {
products:[]
};
}
componentDidMount() {
fetch("http://localhost:3000/data/testMocup.json")
.then(res => res.json())
.then(res => {
this.setState({ products: res.data.item})
})
}
render() {
return(
<div className="Productcolumn">
<Nav />
{/* <Productfilternav /> */}
{this.state.products.length>0 && <Mapcomponent products={this.state.products} />}
<Footer />
</div>
);
}
}
export default MapList;
최상단 컴포넌트의 코드
import React, { Component } from "react";
import { Link } from 'react-router-dom';
import Mapcategoryinfo from "./Mapcategoryinfo";
import Mapgoods from "./Mapgoods";
import Underbar from "./Underbar";
import "./Mapcomponent.scss";
class Mapcomponent extends Component {
constructor(props) {
super(props);
}
render() {
const products = this.props.products;
const categoryInfo= products[0].category_info;
const goods = products[0].products;
return(
<>
<section className="Mapcomponent">
<Mapcategoryinfo categoryInfo={categoryInfo} />
<Mapgoods goods={goods} />
</section>
<Underbar products={products} />
</>
)
}
}
export default Mapcomponent;
2번째의 컴포넌트에서 해당 태그들의 내용을 따로 따로 뿌려주기 위해서 만들었다.
import React, { Component } from "react";
import "./Mapcategoryinfo.scss";
class Mapcategoryinfo extends Component {
constructor() {
super();
}
render() {
const category= this.props.categoryInfo;
return(
<>
<div className="Mapcategoryinfo">
<div className="textTitleBOX">
<div className="introTitle">
<div className="introDescription">
<h2 className="introDescriptionHeadline" >
{category.description_title}
</h2>
<p className="introDescriptionINFO">
{category.description_content}
</p>
</div>
</div>
</div>
</div>
</>
);
}
}
export default Mapcategoryinfo;
카테고리 인포의 내용을 뿌려주기 위해서 따로 만들었다.
import React, { Component } from "react";
import Mapgood from "./Mapgood";
import "./Mapgoods.scss";
class Mapgoods extends Component {
constructor() {
super();
}
render() {
const goods =this.props.goods;
return (
<>
{goods.map(product => {
return (
<Mapgood product={product} />
);
})
}
</>
)}
}
export default Mapgoods;
제품들의 배열을 받아 1개씩의 배열을 자르기 위해서 만든 컴포넌트.
import React, { Component } from "react";
import { Link } from 'react-router-dom';
import "./Mapgood.scss";
class Mapgood extends Component {
constructor() {
super();
this.state = {
btnChange: true,
display: false,
}
}
hadleChangeBtn = (e) => {
this.setState ({
btnChange : false
});
}
hoverOverChange = (e) => {
this.setState({
display: true
});
}
hoverOutChange = (e) => {
this.setState({
display : false
})
}
render() {
const product = this.props.product;
return(
<div onMouseOver={this.hoverOverChange} onMouseOut={this.hoverOutChange} className={this.state.display ?
`hoverState subcategoryProducts `: `nonehoverState subcategoryProducts`}>
<div className="subcatProductWrapper">
<div className="pictureImgLinkControl">
<Link className="pictureImgLinkTag" to="">
<div className="productPicture">
<img className="pictureImg" src={product.image_url} alt=""></img>
</div>
</Link>
</div>
<div className="productSizePrice">
<Link className="textdeco" to="" >
<h5 className="productSizePriceName">{product.name}</h5>
<div className="productSizePriceInfo">
<span>{product.size.size}</span>
<span className="spanSlash">/</span>
<span>{product.size.price}</span>
</div>
</Link>
</div>
<div className="productDetailLink">
{/* <Link to=""> */}
<div className="productDetails">
<ul className="productList">
<li className="productDetailsListItem">
<div className="productDetailsTitle">피부 타입</div>
<div className="productDetailsContent">{product.skin_types.name}</div>
</li>
<li className="productDetailsListItem">
<div className="productDetailsTitle">사용감</div>
<div className="productDetailsContent">{product.usability}</div>
</li>
</ul>
</div>
<div className={this.state.display ?
`hoverState productWrapper` : `nonehoverState productWrapper`} >
<button className="productCartBtn" type="button">
<div className="btnContent">
<span onClick={this.hadleChangeBtn} className={this.state.btnChange ? "btnLabel" : "noneBtnLabel"}>카트에 추가 — {product.size.price}</span>
<span className={this.state.btnChange ? "btnLabelAction" : "nonebtnLabelAction" }>카트에 추가됨</span>
<span className="loadingIndicatorLight"></span>
</div>
</button>
</div>
{/* </Link> */}
</div>
</div>
</div>
)
}
}
export default Mapgood;
마지막으로 1개씩 잘라진 배열을 출력하기 위한 설정.
import React, { Component } from "react";
import "./Underbar.scss";
class Underbar extends Component {
constructor() {
super();
this.state = {
products : []
}
}
render() {
return(
<>
<div className="nextpageDark">
<div className="nextpageWrapper">
<div className="nextpageImgWrapper">
<div className="nextpageImgBOX">
<img className="nextpageImgSize" src="https://www.aesop.com/medias/Aesop-Skin-Purifying-Facial-Exfoliant-Paste-75mL-small.png?context=bWFzdGVyfGltYWdlc3wxODQyNTB8aW1hZ2UvcG5nfGltYWdlcy9oZDYvaDViLzg3OTc0NDY1MzcyNDYucG5nfDkxZjEyOWIzNzE2YjBhYjg2MGJjOWU5ZjE0ZTFmYjBiZDcyYzU4OTY4NjNlMDVlZDZmOTVmZjFhYWU1MmIxMTY" />
</div>
</div>
<div className="nextpageInfo">
<h5 className="nextpageInfoTitle">다음 단계</h5>
<h2 className="nextpageInfoContent">마찰로 만드는 아름다움</h2>
<div className="nextpageBtnWrapper">
<button className="nextpageBtn" type="button">
<div className="btnContent">
<span className="btnLabel">각질제거</span>
<svg className="btnIconBector" role="img" viewBox="0 0 50 50">
<g>
<path d="M30.1,5.3L50,25.1L30.1,45h-6.6l18-17.6H0v-4.8h41.5l-18-17.6h6.6V5.3z"></path>
</g>
</svg>
</div>
</button>
</div>
</div>
</div>
</div>
</>
)
}
}
export default Underbar;
마지막으로 언더바 부분.
아직은 하드 코딩으로 설정해두었다. 이거 수정할 시간이 없어서 그냥 출력했는데, 실제 데이터가 들어오면 그냥 바꾸려고 준비중이다.
결국 그냥 컴포넌트를 여러가지로 나누었는데, 나의 약점이 발견.
this.state.prouducts로 넘겨주면 this.props.products로 받아야 하는데,
비구조 할당을 하려다보니 const {script} = this.props로 받았더니 안받아짐...
파트멘토님이 설명해주었는데, 이리 받으면 안되고 const {products} = this.props로 받아야한다고 말씀해주심.
componentDIdUpdate 공부하라고 하셨는데, 못함... 프로젝트때문에 그거 들을 시간이 충분하지 않았다...ㅠ-ㅠ
각설하고, 여러가지 컴포넌트로 나누었더니, 해당 컴포넌트를 자연스럽게 호버가 되었고, 이를 통해서 동시선택문제를 해결했다.
나의 경우 activeTab은 쓸모가 없었다. why? 그것은 일일히 하드코딩으로 컴포넌트를 연결해서 작업하는 부분이었기에 map 돌려야하는 나에게는 전혀 필요없었던 부분.
그리고 백엔드쪽에서 json을 주었는데, 이 자료로 매우 고생했다.
왜냐하면 경로 설정이 안되어서 접근이 안되었는데, 그 이유가
data : [ categoryinfo : {}, nextcategory: {}, item [ products : [ title:해당 값.]]
배열[객체-객체-배열-객체-배열-객체] 이렇게 주었기때문이었다.
이러니 아무리해도 이상하게 접근이 안되지.
데이터 연결하고 돌리는데 대략 시간낭비만 5~6시간...미치는 줄 알았다.
아까 백엔드쪽에서 데이터를 받았는데, 이를 경로설정하고 구동되도록 설정한 부분이 작동되지 않아서 매우 고생하였는데, 백엔드 데이터가 아직 완벽하지 않아서 더 수정하고 다시 맵을 돌려 연결해야한다.
마지막으로
컴포넌트를 부를때
1번
2번
3번
컴포넌트를 부르고 display: flex, flex-direction에서 column을 주었더니
그냥
1
2
3
이렇게 나열되는 것이었다.
바로 display: flex flex-wrap: wrap을 주었더니
요렇게 나열되었다.
하지만 1번 컴포넌트의 크기 값을 설정하지 않고 그냥 최상단으로 감싸는 것을 했더니 div블록마냥 전체구역을 먹길래
바로 최상단 className을 설정하여, 해당 크기를 줄이고 완성하였다.
문제는 이제 버튼부분을 수정하는 부분...
modal pop부분도 로그인을 만든 내가 구현해야했지만, 팀원이 이미 다 끝내어서 다 해버렸다.
나는 오늘 이거 구현하는데 너무 많은 시간을 낭비했기에...
pagination?
말 그대로 페이지 이벤트이다.
offset을 설정하여 초기값을 설정하고
보여줄 갯수를 50개 설정해서 user가 화면을 내리면 `${offset} +50` 이렇게 적용하여 계속 새로운 화면을 뛰우게 하는 방법이다.
이러한 이벤트가 있는 이유는 user에게 보여줄 데이터가 너무 많을 경우 이러한 통신을 위해서 데이터 서버의 무리한 자원낭비 부담을 줄이기 위함이다.
그냥 한마디로 instagram이나 pinterest와 같은 사이트들에서 보는 이벤트로 보면 되고 많은 업체들이 사용하고 있다.
'코딩 > 위코드 코딩학습' 카테고리의 다른 글
[위코드] TIL(Today I am learned) -21(1차 프로젝트) (0) | 2020.08.02 |
---|---|
[위코드] TIL(Today I am learned) -20 (0) | 2020.07.30 |
[위코드] TIL(Today I am learned) -18(onMouse이벤트/computed property named) (0) | 2020.07.28 |
[위코드] TIL(Today I am learned) -17 (0) | 2020.07.27 |
[위코드] TIL(Today I am learned) -16 (0) | 2020.07.27 |