Component in Component
어쩔수없이 저번까지 진행한 소스 내용
(App.js 지금까지)
import './App.css';
import React, {useState} from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Button, Container,Navbar, Nav, NavDropdown, Card} from 'react-bootstrap'
import {Route, Link, Switch} from 'react-router-dom'
import {} from 'react-bootstrap'
import Data from './data.js'
import Detail from './Detail';
import axios from 'axios'
function App() {
let [shoes, shoes변경] = useState(Data)
return (
<div className="App">
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">Shoe Shop</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link><Link to="/">Home</Link></Nav.Link>
<Nav.Link><Link to="/detail">Detail</Link></Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<Switch>
{/* 상위 페이지 */}
<Route exact path="/">
<Card style={{ width: '100%' }}>
{/* <Card.Img variant="top" src="holder.js/100px180" /> */}
<Card.Body>
<Card.Title>Welcome!</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up the bulk of
the card's content.
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
<div className="container">
<div className="row">
{
shoes.map( (shoe, idx)=> {
return <Goods shoes={shoe} key={idx} />
})
}
</div>
<button className="btn btn-primary" onClick={
()=> {
// 로딩 중 표시 할수도
axios.get('https://codingapple1.github.io/shop/data2.json')
// ajax의 결과를 result에 담아둔다.
.then( (result)=> {
// ajax로 받아온 결과물을 추가
// 복사본만들기위해, ... 사용, 대괄호를 벗겨라?
// 로딩 중 표시 없애기
shoes변경( [...shoes, ...result.data ] );
})
.catch( ()=> {
console.log("Failed");
})
}}>더 보기</button>
</div>
</Route>
<Route path="/detail/:id">
<Detail shoes={shoes} />
</Route>
{/* /:
'/모든문자' 라는 경로를 의미
여러개가
*/}
<Route path="/:id">
<div>무조건 보이기</div>
</Route>
</Switch>
</div>
);
}
function Goods(props) {
return (
<div className="col-md-4">
<img src={"https://codingapple1.github.io/shop/shoes"+props.shoes.id +".jpg"} width="100%" />
<h4>{props.shoes.title}</h4>
<p>{props.shoes.price}</p>
</div>
)
}
export default App;
상품 재고 표시
- 일단 재고량은 테스트 데이터를 state로 만들어보기
let [재고, 재고변경] = useState( [10,11,12] );
- 되도록 중요하게 처리할 데이터는 상위 component에 놓는다
이 데이터를 Detail까지 데이터바인딩 할 것이다.
(Detail.js 여기까지)
import React, {useState, useEffect } from "react"
import {useHistory} from 'react-router-dom'
import {useParams} from 'react-router-dom'
import styled from 'styled-components'
import './Detail.scss'
function Detail(props) {
// `글자 ${변수명}글자`
let hist = useHistory(); // react-router-dom ver5 이상, 방문기록 등을 저장해놓은 object라 이해
let {id} = useParams(); //사용자가 입력한 URL 파라미터들, /:id 자리에 입력된 값
let 찾은상품 = props.shoes.find( x=> x.id==id);
// css를 미리 입려놓은 컴포넌트?
let 박스 = styled.div`
padding : 20px;
border-style: ridge;
`;
let 제목 = styled.h4`
font-size: 25px;
`;
// UI 보이고/안보이고하는 상태를 state로 저장
let [alert, alert변경] = useState(true);
let [inputData, inputData변경] = useState();
// 컴포넌트가 mount, update 될때 특정코드 실행할 수 있다
useEffect(() => {
let timer = setTimeout( ()=> {
alert변경(false);
}, 2000);
}, [alert]);
return (
<div className="container">
<박스>
<제목 className="red">상세페이지</제목>
</박스>
{
alert === true
? <div className="my-alert">
<p>재고가 얼마 남지 않았습니다.</p>
</div>
: null
}
<div className="row">
<div className="col-md-4">
<img src={"https://codingapple1.github.io/shop/shoes"+찾은상품.id+".jpg"} width="100%" />
</div>
<div className="col-md-6 mt-4">
<h4 className="pt-5">{찾은상품.title}</h4>
<p>{찾은상품.content}</p>
<p>{찾은상품.price}</p>
<Info 재고={props.재고} />
<button className="btn btn-danger">주문하기</button>
<button className="btn btn-danger" onClick={()=>{hist.goBack()}}>뒤로가기</button>
</div>
</div>
</div>
)
}
function Info() {
return (
<p>재고: {props.재고[0]}</p>
)
}
export default Detail;
재고 정보는 component로 만들어서 넣어보기로
Info 컴포넌트 만들고 props 로 전달 [ App.js > Detail > Info ]
props로 하위로 값 전달 [Detail > Info]
<Info 재고={props.재고} />
(Detail.js)
function Info(props) {
return (
<p>재고: {props.재고[0]}</p>
)
}
export default Detail;
state변경함수도 props로 전달 가능
생성하는 컴포넌트가 많을 수록 앱은 복잡해진다 -> Context API 혹은 redux를 써야한다고...
리액트 사이트 build
사이트를 배포하기 위해선, App.js 파일 그대로 올리는게 아니라
build용 파일을 생성한 후 그걸 올려야 한다.
리액트의 각종 문법 등을 브라우저가 이해하고 해석할수 있도록 html, css 같은 걸로 바꿔준다
npm run build [ yarn build]
'프로그래밍&IT > React & CSS' 카테고리의 다른 글
Coding Apple, React 강좌 내용 정리.17 - Redux.1 (0) | 2021.11.04 |
---|---|
Coding Apple, React 강좌 내용 정리.16 - Tab UI , animation (0) | 2021.11.03 |
Coding Apple, React 강좌 내용 정리.14 - Ajax in React (0) | 2021.11.03 |
Coding Apple, React 강좌 내용 정리.13 - useEffect 훅(hook) (0) | 2021.11.03 |
Coding Apple, React 강좌 내용 정리.12 - styled-components (0) | 2021.11.03 |