일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- peerdependencies
- 딥다이브
- js pattern
- js pattern
- 올림픽 통계 서비스 최적화
- mixin pattern
- 모던 자바스크립트 Deep Dive
- 블로그 서비스 최적화
- const
- 제너레이터와 async/await
- unique identifiers
- 학습내용정리
- Babel과 Webpack
- 브라우저의 렌더링 과정
- package management
- 이미지 갤러리 최적화
- 자바스크립트
- DOM
- 자바스크립트 패턴
- middleware pattern
- 프론트엔드 성능 최적화 가이드
- 자바스크립트 딥다이브
- 새 코드 받아오기
- 진행기록
- 이벤트
- 스코프
- version management
- pr review
- 커리어
- 프로그래머스
- Today
- Total
Dev Blog
(Youtube)Amazon Clone Project(Day1) 본문
아마존 클론 코딩 목적
1. 비즈니스 모델인 이커머스 웹사이트의 구현 방법 학습
1) Comprehensive Layout & CSS
2) Login & Authentication
3) Payment Process
4) Order History
2. 해당 프로젝트로 Redux 재 학습
3. 이커머스 관련 프로젝트 진행을 위한 코드 구조 및 구현 프로세스 파악
금일 진행 사항
[Part1]Getting Set Up
- Set up new react app and firebase
[Part2]The Home Page
- Made Header and Home page
- Amazon styled-CSS and layout applied
[Part3]The Checkout Page
- Design Checkout Page
- Set up Redux(reducer, state provider etc)
- Make 'ADD TO CART' function in reducer
[Part3.5]More Checkout Page
- Design Shopping Basket
- Add Remove Button function by using dispatch and reducer
[Part3]The Checkout Page - Set up Redux(reducer, state provider etc)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {StateProvider} from './StateProvider'
import reducer, {initialState} from './reducer'
ReactDOM.render(
<React.StrictMode>
<StateProvider reducer={reducer} initialState ={initialState}>
<App />
</StateProvider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
import React, {createContext, useContext, useReducer} from 'react'
//Prepares the dataLayer
export const StateContext = createContext();
// Wrap our app and provide the Data layer to every components
export const StateProvider = ({reducer, initialState, children}) => {
return <StateContext.Provider value={useReducer(reducer, initialState)}>{children}</StateContext.Provider>
}
//Pull information from the data layer
export const useStateValue = () => useContext(StateContext)
1) createContext
- context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.
2) Context.Provider
<MyContext.Provider value={/* 어떤 값 */}>
- Context 오브젝트에 포함된 React 컴포넌트인 Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알리는 역할을 합니다.
- Provider 컴포넌트는 value prop을 받아서 이 값을 하위에 있는 컴포넌트에게 전달합니다. 값을 전달받을 수 있는 컴포넌트의 수에 제한은 없습니다.
- Provider 하위에서 context를 구독하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.
3) useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
- useState의 대체 함수입니다. (state, action) => newState의 형태로 reducer를 받고 dispatch 메서드와 짝의 형태로 현재 state(데이터)를 반환합니다.
- 다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우나 다음 state가 이전 state에 의존적인 경우에 보통 useState보다 useReducer를 선호합니다. 또한 useReducer는 자세한 업데이트를 트리거 하는 컴포넌트의 성능을 최적화할 수 있게 하는데, 이것은 콜백 대신 dispatch를 전달 할 수 있기 때문입니다.
4) useContext
const value = useContext(MyContext);
- context 객체(React.createContext에서 반환된 값)을 받아 그 context의 현재 값을 반환합니다.
- 컴포넌트에서 가장 가까운 <MyContext.Provider>가 갱신되면 이 Hook은 그 MyContext provider에게 전달된 가장 최신의 context value(데이터)를 사용하여 렌더러를 트리거 합니다.
출처: ko.reactjs.org/docs/context.html
reducer.js
export const initialState = {
basket: [],
user: null
}
//Selector
export const getBasketTotal = (basket) =>
basket?.reduce((amount, item) => item.price + amount, 0);
//? function of '?'
const reducer = (state, action) => {
// console.log(action)
// console.log(state)
switch(action.type) {
case 'ADD_TO_BASKET':
return {
...state,
basket: [...state.basket, action.item],
};
case 'REMOVE_FROM_BASKET':
const index = state.basket.findIndex(
(basketItem) => basketItem.id === action.id
)
let newBasket = [...state.basket]
if(index >=0) {
newBasket.splice(index, 1)
} else {
console.warn(`Can't remove prodect (id:${action.id}) as it is not in basket!!`)
}
return {
...state,
basket: newBasket
}
default:
return state;
}
}
export default reducer;
Product.js(ADD TO BASKET)
import React from 'react'
import './Product.css'
import { useStateValue } from './StateProvider'
function Product({id, title, image, price, rating}) {
const [, dispatch] = useStateValue(); //state = {basket:Array(2)}
const addToBasket = () =>{
//dispatch the item into the data layer
dispatch({
type: 'ADD_TO_BASKET',
item: {
id: id,
title:title,
image: image,
price: price,
rating: rating
}
})
}
return (
<div className="product">
<div className="product__info">
<p>{title}</p>
<p className="product__price">
<small>$</small>
<strong>{price}</strong>
</p>
<div className="product__rating">
{Array(rating).fill().map((_, i)=>(
<p key={i}>🌟</p>
))}
</div>
</div>
<img src={image} alt=""></img>
<button onClick={addToBasket}>Add to Basket</button>
</div>
)
}
export default Product
CheckoutProduct.js(REMOVE FROM BASKET)
import React from 'react'
import './CheckoutProduct.css'
import {useStateValue} from './StateProvider'
function CheckoutProduct({id, image, title, price, rating, hideButton}) {
const [, dispatch] = useStateValue();
const removeFromBasket = (e) =>{
dispatch({
type: 'REMOVE_FROM_BASKET',
id: id
})
}
return (
<div className="checkoutProduct">
<img className="checkoutProduct__image" src={image} alt=""/>
<div className="checkoutProduct__info">
<p className="checkoutProduct__title">{title}</p>
<p className="checkoutProduct__price">
<small>$</small>
<strong>{price}</strong>
</p>
<div className="checkoutProduct__rating">
{Array(rating).fill().map((_, i) => (<p>🌟</p>))}
</div>
{hideButton ? null : <button onClick={removeFromBasket}>remove from basket</button>}
</div>
</div>
)
}
export default CheckoutProduct
리덕스 개념 설명 코드
const { createStore } = require("redux");
//!초기 state(데이터)를 정의한다.
const initState = {
name: "김코딩",
posts: [],
};
//!action creator
//!action 은 객체로 data 를 받으면 type 과 payload(여기에서 data) 가 reducer 에게 전달된다.
const changeUsername = (data) => {
return {
type: "CHANGE_NAME",
data,
};
};
const addPost = (post) => {
return {
type: "ADD_POST",
post,
};
};
//! reducer: 실제 메소드로 데이터를 변경해준다.
//! initState(prevState)와 action 을 받아 type 에 따라
//! payload를 활용하여 특정 method 를 실행시킨다.
const reducer = (prevState, action) => {
switch (action.type) {
case "CHANGE_NAME":
return {
...prevState,
name: action.data,
};
case "ADD_POST":
return {
...prevState,
posts: [...prevState.posts, action.post],
};
default:
return prevState;
}
};
//! Store
//! createStore 메소드를 활용. createStore(reducer, [preloadedState], [enhancer])
//! reducer: returns the next state tree, given the current state tree and an action to handle.
//! [preloadedState]: initState
//! [enhandcer]: to enhance the store with third-party capabilities such as middleware, time travel, persistence, etc.
const store = createStore(reducer, initState);
//! dispatch
//! The base dispatch function always synchronously sends an action to the store's reducer,
//! along with the previous state returned by the store, to calculate a new state.
//! It expects actions to be plain objects ready to be consumed by the reducer.
store.dispatch(changeUsername("김제이"));
store.dispatch(addPost("포스트1"));
store.dispatch(addPost("포스트2"));
console.log(store.getState());
Lecture from:
youtu.be/RDV3Z1KCBvo
medium.com/cleverprogrammer/amazon-clone-using-react-the-ultimate-guide-fba2b36f3458
'Projects > Amazon Clone' 카테고리의 다른 글
(Youtube)Amazon Clone Project(Day3) (0) | 2021.04.26 |
---|---|
(Youtube)Amazon Clone Project(Day2) (0) | 2021.04.26 |