import React, {useState, useEffect} from 'react';

function Detail(props){
    let [alert, alert변경] = useState(true);
    let [inputData, inputData변경] = useState('');

    useEffect(()=>{
        let 타이머 = setTimeout(()=>{ alert변경(false)}, 2000);
        console.log('dkasfj');
        return ()=>{ clearTimeout(타이머) }
    },[alert]);
    //조건(alert)의 변경이 있으면, 실행됨 useEffect(()=> 실행함수,[alert]);
    //Detatil 구성이 끝나면, 실행됨 return()=>{ 실행함수 }

    return(
        <div className="container">
            {
                alert === true
                ? (<div id="addv" className="my-alert-yellow">
                        <p>재고가 얼마 남지 않았습니다.</p>
                    </div>)
                : null
            }
			//3항 연산자, 조건?참일때 수행함수:거짓일때 수행함수
        </div> 
    )
}

export default Detail;
//파일명.scss  -> 임포트하려는 파일의 상단에 import './파일명.scss';

// 다른 파일 임포트 가능
@import "./reset.scss";

//자주쓰는 값 변수로 저장 가능
$메인칼라: #ff0000;
.red {
  color: $메인칼라;
}

.my-alert {
  background: #eeeeee;
  padding: 20px;
  border-radius: 5px;
}

// 확장 가능
.my-alert-yellow {
  @extend .my-alert;
  background: #ffe591;
}

//함수로 정의해서 사용 가능
@mixin 함수() {
  background: #eeeeee;
  padding: 20px;
}
.my-alert-add {
  @include 함수();
}

// 네스팅 가능
 div.container h4 {
   color: blue;
 }
 div.container p {
   color:green;
 }

 div.container {
   h4 {
     color: blue;
   }
   p {
     color: green;
   }
 }

메인 페이지: route로 상세페이지 불러오기

/*eslint-disable-next-line*/
import React, {useState} from 'react';
import { Button,Navbar,Nav,NavDropdown,Jumbotron,} from 'react-bootstrap';
import './App.css';
import Data from './data.js';
import Detail from './Detail.js';
import { Link, Route, Switch } from 'react-router-dom';

function App() {
  let [shoes, shoes변경] = useState(Data);
  return (
    <div className="App">
      <Switch>
        <Route exact path="/">
          메인페이지
        </Route>
        <Route path="/detail/:id">
          상세페이지
          <Detail shoes={shoes}/>
        </Route>
      </Switch>     
    </div>
  );
}

export default App;

 

 

상세페이지

import React, {useState} from 'react';
import {useHistory, useParams } from 'react-router-dom';

function Detail(props){
    // {사용자가 입력한 URL 파라미터 값이 넘어옴}
    let { id } = useParams();
    // return 오른쪽에 조건식을 만족하면, '찾은상품'에 값이 저장됨
    let 찾은상품 = props.shoes.find(function(상품){
        return 상품.id == id
    });
    return(
        <div className="container">
            <div className="row">
                <div className="col-md-6">
                    <img src={'https://codingapple1.github.io/shop/shoes1.jpg'} width="100%" />
                </div>
                <div className="col-md-6 mt-4">
                    <h4 className="pt-5">{찾은상품.title}</h4>
                    <p>{찾은상품.content}</p>
                    <p>{찾은상품.price}원</p>
                    <button className="btn btn-danger">주문하기</button> 
                    <button className="btn btn-danger" onClick={()=>{ history.push('/')}}>뒤로가기</button> 
                </div>
            </div>
        </div> 
    )
}
export default Detail;
/*eslint-disable-next-line*/
import React, {useState} from 'react';
import { Button,Navbar,Nav,NavDropdown,Jumbotron,} from 'react-bootstrap';
import './App.css';
import Data from './data.js';
import Detail from './Detail.js';

import { Link, Route, Switch } from 'react-router-dom';

function App() {
  let [shoes, shoes변경] = useState(Data);

  return (
    <div className="App">
      <Navbar bg="light" expand="lg" className="navbar">
        <Navbar.Brand href="#home">모자팔이</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto">
            <Nav.Link><Link to="/">Home</Link></Nav.Link>
            <Nav.Link><Link to="/detail">Detail</Link></Nav.Link>
            <Nav.Link><Link to="/Hello">Hello</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>
      </Navbar>

      <Switch>
        <Route exact path="/">
          <Jumbotron className="jumbotron">
              <h1>20% 시즌 오프</h1>
              <p>
                This is a simple hero unit, a simple jumbotron-style component for calling
                extra attention to featured content or information.
              </p>
              <p>
                <Button variant="primary">Learn more</Button>
              </p>
          </Jumbotron>
        <div className="container">
          <div className="row">
            {shoes.map(function(shoe,i){
              return(<DescGood shoe={shoe} i={i} key={i}/>)
            })}
          </div>
        </div>
        </Route>
        <Route path="/detail">
            <Detail/>
        </Route>
        <Route path="/hello">
          <div>sadfasdf</div>
        </Route>
        {/* <Route path="/어쩌구" component={Modal}></Route> */}
      </Switch>
      
    </div>
  );
}

function DescGood(props){
  return(
    <div className="col-md-4">
      <img src={'https://codingapple1.github.io/shop/shoes'+ (props.i+1) +'.jpg'}></img>
      <h4>{ props.shoe.title }</h4>
      <p>{ props.shoe.content } & { props.shoe.price }</p>
    </div>
  )
}

export default App;

1. 설치

yarn add react-router-dom

npm install react-router-dom

 

2. index.js에 아래 추가

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App/>
    </BrowserRouter>
  </React.StrictMode>
  document.getElementById('root')
);

3. app.js에 라우팅하는 방법

import { Link, Route, Switch } from 'react-router-dom';

function App(){
  return (
    <div>
    
      <Route exact path="/"> 
        HTML 소스
      </Route>
      
      <Route path="/detail">
        HTML 소스
      </Route>
      <Route path="/어쩌구"> <Card/> </Route> //컴퍼넌트(<Card />)로 작성도 가능
      
    </div>
  )
}
var Data = [
    {
      id : 0,
      title : "White and Black",
      content : "Born in France",
      price : 120000
    },
  
    {
      id : 1,
      title : "Red Knit",
      content : "Born in Seoul",
      price : 110000
    },
  
    {
      id : 2,
      title : "Grey Yordan",
      content : "Born in the States",
      price : 130000
    }
  ] ;


export default Data;

/*eslint-disable-next-line*/
import React, {useState} from 'react';
import { Button,Navbar,Nav,NavDropdown,Jumbotron,} from 'react-bootstrap';
import './App.css';
import Data from './data.js';

function App() {

  let [shoes, shoes변경] = useState(Data);

  return (
    <div className="App">
      <div className="container">
        <div className="row">
          {shoes.map(function(shoe,i){
            return(<DescGood shoe={shoe} i={i} key={i}/>)
          })}
        </div>
      </div>
    </div>
  );
}

function DescGood(props){
  return(
    <div className="col-md-4">
      <img src={'https://codingapple1.github.io/shop/shoes'+ (props.i+1) +'.jpg'}></img>
      <h4>{ props.shoe.title }</h4>
      <p>{ props.shoe.content } & { props.shoe.price }</p>
    </div>
  )
}

export default App;
var Data = [
    {
      id : 0,
      title : "White and Black",
      content : "Born in France",
      price : 120000,
      src : "https://codingapple1.github.io/shop/shoes1.jpg"
    },
  
    {
      id : 1,
      title : "Red Knit",
      content : "Born in Seoul",
      price : 110000,
      src : "https://codingapple1.github.io/shop/shoes2.jpg"
    },
  
    {
      id : 2,
      title : "Grey Yordan",
      content : "Born in the States",
      price : 130000,
      src : "https://codingapple1.github.io/shop/shoes3.jpg"
    }
  ] ;


export default Data;
​
/*eslint-disable-next-line*/
import React, {useState} from 'react';
import { Button,Navbar,Nav,NavDropdown,Form,FormControl, Jumbotron,Container,Row,Col,img } from 'react-bootstrap';
import './App.css';
import Data from './data.js';

function App() {

  let [shoes, shoes변경] = useState(Data);

  return (
    <div className="App">
      <div className="container">
        <div className="row">
          <div className="col-md-4">
            <img src={shoes[0].src}></img>
            <h4>{ shoes[0].title }</h4>
            <p>{ shoes[0].content } & { shoes[0].price] }</p>
          </div>
        </div>
      </div>
    
    </div>
  );
}

export default App;

navbar, jumbotron, 3등분

/*eslint-disable-next-line*/
import React, {useState} from 'react';
import { Button,Navbar,Nav,NavDropdown,Form,FormControl, Jumbotron,Container,Row,Col,img } from 'react-bootstrap';
import './App.css';

function App() {


  return (
    <div className="App">

      <Navbar bg="light" expand="lg" className="navbar">
        <Navbar.Brand href="#home">모자팔이</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#link">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>
      </Navbar>

      <Jumbotron className="jumbotron">
        <h1>20% 시즌 오프</h1>
        <p>
          This is a simple hero unit, a simple jumbotron-style component for calling
          extra attention to featured content or information.
        </p>
        <p>
          <Button variant="primary">Learn more</Button>
        </p>
      </Jumbotron>
      
      <Container className="container">
        <Row className="col">
          <Col xs={12} md={4} className="col-md-4">
            <img src="https://codingapple1.github.io/shop/shoes1.jpg"></img>
            <h4>상품명</h4>
            <p>상품설명 & 가격</p>
          </Col>
          <Col xs={12} md={4} className="col-md-4">
            <img src="https://codingapple1.github.io/shop/shoes2.jpg"></img>
            <h4>상품명</h4>
            <p>상품설명 & 가격</p>
          </Col>
          <Col xs={12} md={4} className="col-md-4">
            <img src="https://codingapple1.github.io/shop/shoes3.jpg"></img>
            <h4>상품명</h4>
            <p>상품설명 & 가격</p>
          </Col>
        </Row>
      </Container> 

    </div>
  );
}

export default App;

0.  yarn (안해도됨)

yarn  설치 - 사이트 구글링

yarn 사용법 - yarn add 00(install 방법), yarn start(개발 서버 구동)

 

2. 새로운 앱 프로젝트 생성

VScode로 폴더 열기->해당 폴더에서 npx create-react-app 00(프로젝트 이름)

VScode로 프로젝트 이름의 폴더 열기

 

3. Bootstrap 라이브러리 사용 (react bootstrap 사이트 참조)

(1) 터미널에 npm install react-bootstrap bootstrap 또는 yarn add react-bootstrap bootstrap 입력

(2) css 넣어주기

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
      integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
      crossorigin="anonymous"
    />

(3) 사용

bootstrap 사이트에서 components에서 필요한 구성의 코드 복붙

import React, {useState} from 'react';
import './App.css';

function App() {
  let [글제목, 글제목변경] = useState(['남자코트 추천', '우동맛집 추천', '파이썬 독학']);
  let [입력값, 입력값변경] = useState('');
  
  function 글제목저장(){
    var newArray = [...글제목];
    newArray.push(입력값);
    글제목변경(newArray);
  }

  return (
    <div className="App">
      {
        글제목.map((글, i)=>{
          return (
            <div className="list" key={i}>
              <h3>{ 글 }</h3>
              <p>2월 17일 발행</p>
              <hr />
            </div>
          )
        })
      }

      <div className="publish">
        <input onChange={(e)=>{ 입력값변경(e.target.value) }}></input>
        <button onClick={()=>{ 글제목저장() }}>글저장</button>
      </div>      
    </div>
  );
}

export default App;

+ Recent posts