일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- axios
- firebase
- JS
- 파이어베이스
- localstorage
- react localStorage
- til
- CORS
- Redux
- es6
- 자바스크립트
- 프론트엔드
- array
- 리액트
- Frontend
- 비트 연산자
- 프로그래머스
- 알고리즘
- v9
- 브라우저
- 타입스크립트
- 프리온보딩
- TypeScript
- react
- state
- Component
- 원티드
- 컴포넌트
- Reducer
- JavaScript
- Today
- Total
도리쓰에러쓰
[React] Redux1 :: props 대신 사용하기 본문
저번 게시물에 이어서 작성하겠습니다. (코드 참고)
1. cart 페이지 만들기
1️⃣ Cart.js 파일 생성 후 아래 코드를 작성합니다.
import React from 'react';
import { Table } from 'react-bootstrap';
function Cart() {
return(
<div>
<Table responsive>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>
</tbody>
</Table>
</div>
)
}
export default Cart;
2️⃣ App.js에서 Cart.js를 import합니다.
import Cart from './Cart.js';
3️⃣ App.js에서 <Route>를 하나 추가합니다.
* localhost:포트번호/cart 로 접속이 가능해집니다.
<Route path="/:id">
<div>아무말</div>
</Route>
2. Redux 이용하여 데이터바인딩하기
1️⃣ 터미널에서 npm install redux react-redux 혹은
yarn이 설치되어 있으신 분들은 yarn add redux react-redux를 입력하여 redex와 react-redux를 동시에 설치합니다.
2️⃣ index.html에서 Provider를 import합니다.
import { Provider } from 'react-redux';
3️⃣ <Provider>로 <App />을 감쌉니다.
💡 감싸진 <App /> Component는 props 없이도 state 공유가 가능합니다.
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Provider>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
4️⃣ createStore() 안에 state 저장하기 위해 createStore import하고 변수를 생성합니다.
그리고 createStrore() 안에 상품 정보 state를 return하는 함수를 생성합니다.
import { createStore } from 'redux';
let store = createStore(()=>{
return [
{ id : 0, name : 'white bag', quan : 2 },
{ id : 1, name : 'black bag', quan : 5 },
{ id : 2, name : 'red bag', quan : 0 }
]
});
5️⃣ <Provider>에 변수 store를 props 전송합니다.
<Provider store={store}>
6️⃣ Component에서 변수 store에 있는 state를 사용하려면 아래의 방법으로 하면 됩니다.
1) function 만들기
function store(state){}
2) export default Component명; 주석 처리하기
// export default Cart;
3) export default connect(함수명)(Component명) 작성하기
export default connect(store)(Cart)
4) connect import하기
import { connect } from 'react-redux';
5) store 데이터를 props로 등록하기
function store(state){
return {
state : state
}
}
- 이 function은 redux store 데이터 가져와서 props로 변환해주는 함수입니다.
- state를 props화 시켜준다고 생각하면 됩니다.
6) Cart Component에 props로 받아서 map()으로 반복문 돌려 데이터 출력하기
function Cart(props) {
return(
<div>
<Table responsive>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경</th>
</tr>
</thead>
<tbody>
{
props.state.map((a, i)=>{
return(
<tr key={i}>
<td>{ a.id }</td>
<td>{ a.name }</td>
<td>{ a.quan }</td>
<td></td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
- 아래 사진과 같이 store에 있던 state 데이터가 들어온 것을 확인할 수 있습니다.
🔔 Redux 쓰는 이유
깊은 하위 Component들도 props 여러번 전송없이 state를 직접 갖다쓸 수 있기 때문에 데이터 사용이 용이합니다.
3. 전체 코드
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
let store = createStore(()=>{
return [
{ id : 0, name : 'white bag', quan : 2 },
{ id : 1, name : 'black bag', quan : 5 },
{ id : 2, name : 'red bag', quan : 0 }
]
});
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
App.js
/* eslint-disable */
import React, { useState, useContext } from 'react'
import { Navbar, Container, Nav, NavDropdown, Button } from 'react-bootstrap';
import './App.css';
import data from './data.js';
import Detail from './Detail.js';
import axios from 'axios';
import { Link, Route, Switch } from 'react-router-dom';
import Cart from './Cart.js';
export let inventoryContext = React.createContext();
function App() {
let [products, setProducts] = useState(data);
let [inventory, setInventory] = useState([10, 11, 12]);
return (
<div className="App">
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">Saint Laurent</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link as={Link} to="/">Home</Nav.Link>
<Nav.Link as={Link} to="/detail">Detail</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="/">
<div className='Jumbotron'>
<h1>20% Season Off</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>
</div>
<div className='container'>
<inventoryContext.Provider value={inventory}>
<div className='row'>
{
products.map((a, i) => {
return <Card products={a} num={i} key={i}/>
})
}
</div>
</inventoryContext.Provider>
<button className='btn btn-primary' onClick={()=>{
axios.get('https://codingapple1.github.io/shop/data2.json')
.then((result)=>{
setProducts([...products, ...result.data])
})
.catch(()=>{
console.log('fail');
})
}}>더보기</button>
</div>
</Route>
<Route path="/detail/:id">
<inventoryContext.Provider value={inventory}>
<Detail products={ products } inventory={ inventory } setInventory={ setInventory } />
</inventoryContext.Provider>
</Route>
<Route path="/cart">
<Cart></Cart>
</Route>
<Route path="/:id">
<div>아무말</div>
</Route>
</Switch>
</div>
);
}
function Card(props) {
let inventory = useContext(inventoryContext);
return(
<div className='col-md-4'>
<img className="img" src={ 'images/img'+ (props.num + 1) +'.jpg' } />
<h4>{ props.products.title }</h4>
<p>{ props.products.content }</p>
<p>{ props.products.price }</p>
<p>재고 : { inventory[props.num] }</p>
</div>
)
}
export default App;
Cart.js
import React from 'react';
import { Table } from 'react-bootstrap';
import { connect } from 'react-redux';
function Cart(props) {
return(
<div>
<Table responsive>
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경</th>
</tr>
</thead>
<tbody>
{
props.state.map((a, i)=>{
return(
<tr key={i}>
<td>{ a.id }</td>
<td>{ a.name }</td>
<td>{ a.quan }</td>
<td></td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
function store(state){
return {
state : state
}
}
export default connect(store)(Cart)
// export default Cart;
* 이외의 코드는 이전 게시물에 작성된 코드와 일치합니다.
'코딩애플 (React) > 기초수업(코딩애플) - 3' 카테고리의 다른 글
[React] Redux3 :: state와 reducer가 더 필요하다면? (0) | 2022.01.31 |
---|---|
[React] Redux2 :: reducer / dispatch로 데이터 수정하기 (0) | 2022.01.26 |
[React] Tab 만들기와 리액트에서의 등장 애니메이션 (0) | 2022.01.24 |
[React] Component가 많을 땐 Context API 사용하기 (0) | 2022.01.23 |
[React] 리액트 사이트 build & Github Pages로 배포하기 (0) | 2022.01.23 |