From 862a0a4600e05157eaeb30960ca97e3068318422 Mon Sep 17 00:00:00 2001 From: novice1993 Date: Sun, 10 Sep 2023 02:34:45 +0900 Subject: [PATCH] =?UTF-8?q?[Add]=20=EC=A3=BC=EC=8B=9D=20=EA=B1=B0=EB=9E=98?= =?UTF-8?q?=EB=9F=89=20=EA=B4=80=EB=A0=A8=20=EC=A0=84=EC=97=AD=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주식 거래량(Volume) 관련 전역 상태 생성 - 기존에 지역 상태로 관리하였으나, 다수의 컴포넌트에서 활용되는 경우가 많아서 편의성 및 코드 간결화를 위해 전역 상태로 변경 Issues #17 --- .../components/StockOrderSection/Index.tsx | 4 +- .../StockOrderSection/OrderDicisionBtn.tsx | 28 ++++++-------- .../StockOrderSection/PriceSetting.tsx | 12 +++--- .../StockOrderSection/StockOrderSetting.tsx | 22 +++++------ .../StockOrderSection/StockPriceList.tsx | 2 +- .../StockOrderSection/VolumeSetteing.tsx | 37 +++++++------------ client/src/models/stateProps.ts | 1 + .../src/reducer/StockOrderVolume-Reducer.ts | 16 ++++++++ client/src/store/config.ts | 2 + 9 files changed, 61 insertions(+), 63 deletions(-) create mode 100644 client/src/reducer/StockOrderVolume-Reducer.ts diff --git a/client/src/components/StockOrderSection/Index.tsx b/client/src/components/StockOrderSection/Index.tsx index 567ad5e9..11daa7be 100644 --- a/client/src/components/StockOrderSection/Index.tsx +++ b/client/src/components/StockOrderSection/Index.tsx @@ -3,7 +3,6 @@ import { styled } from "styled-components"; import useGetStockInfo from "../../hooks/useGetStockInfo"; import { stockOrderClose } from "../../reducer/StockOrderSet-Reducer"; import { StateProps } from "../../models/stateProps"; - import StockOrder from "./StockOrder"; import OrderResult from "./OrderResult"; @@ -21,9 +20,9 @@ const StockOrderSection = () => { // 🔴 로그인 구현될 때까지 임시 const [login, setLogin] = useState(true); + const dispatch = useDispatch(); const companyId = useSelector((state: StateProps) => state.companyId); const stockOrderSet = useSelector((state: StateProps) => state.stockOrderSet); - const dispatch = useDispatch(); const { stockInfo, stockInfoLoading, stockInfoError } = useGetStockInfo(companyId); @@ -83,6 +82,7 @@ const LoginRequestIndicator = () => { ); }; +// component 생성 const Container = styled.aside<{ orderSet: boolean }>` position: fixed; z-index: 1; diff --git a/client/src/components/StockOrderSection/OrderDicisionBtn.tsx b/client/src/components/StockOrderSection/OrderDicisionBtn.tsx index c76cbbf5..b430c235 100644 --- a/client/src/components/StockOrderSection/OrderDicisionBtn.tsx +++ b/client/src/components/StockOrderSection/OrderDicisionBtn.tsx @@ -1,8 +1,9 @@ import { useState, useEffect } from "react"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import { styled } from "styled-components"; import { StateProps } from "../../models/stateProps"; import { OrderTypeProps } from "../../models/orderTypeProps"; +import { setStockOrderVolume } from "../../reducer/StockOrderVolume-Reducer"; const availableMoneyText01: string = "최대"; const availableMoneyText02: string = "원"; @@ -12,26 +13,27 @@ const totalAmountUnit: string = "원"; // dummyData const dummyMoney = 10000000; -const OrderDicisionBtn = (props: OwnProps) => { - const { orderVolume, setOrderVolume } = props; - - const stockOrderType = useSelector((state: StateProps) => state.stockOrderType); +const OrderDicisionBtn = () => { + const dispatch = useDispatch(); + const orderType = useSelector((state: StateProps) => state.stockOrderType); const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice); + const orderVolume = useSelector((state: StateProps) => state.stockOrderVolume); const [totalOrderAmout, setTotalOrderAmout] = useState(0); - const orderBtnText: string = stockOrderType ? "매도" : "매수"; + + const orderBtnText: string = orderType ? "매도" : "매수"; useEffect(() => { setTotalOrderAmout(orderPrice * orderVolume); }, [orderPrice, orderVolume]); useEffect(() => { - setOrderVolume(0); + dispatch(setStockOrderVolume(0)); setTotalOrderAmout(0); - }, [stockOrderType]); + }, [orderType]); return (
- + {availableMoneyText01} {dummyMoney.toLocaleString()} {availableMoneyText02} @@ -41,19 +43,13 @@ const OrderDicisionBtn = (props: OwnProps) => {
{totalOrderAmout.toLocaleString()}
{totalAmountUnit}
- {orderBtnText} + {orderBtnText}
); }; export default OrderDicisionBtn; -// type 선언 -interface OwnProps { - orderVolume: number; - setOrderVolume: (orderVolume: number) => void; -} - // component 생성 const AvailableMoney = styled.div<{ orderType: boolean }>` display: flex; diff --git a/client/src/components/StockOrderSection/PriceSetting.tsx b/client/src/components/StockOrderSection/PriceSetting.tsx index dd95e38c..2d5bcaeb 100644 --- a/client/src/components/StockOrderSection/PriceSetting.tsx +++ b/client/src/components/StockOrderSection/PriceSetting.tsx @@ -11,17 +11,15 @@ const unitText: string = "원"; const PriceSetting = (props: OwnProps) => { const { stockInfo, companyId } = props; - const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice); const dispatch = useDispatch(); + const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice); // 초기 설정값 및 가격 변동폭 설정 const { askp1, askp2, askp3, askp4, askp5 } = stockInfo; const sellingPrice = [parseInt(askp1), parseInt(askp2), parseInt(askp3), parseInt(askp4), parseInt(askp5)]; - const existSellingPrice = sellingPrice.filter((price) => price !== 0); + const existSellingPrice = sellingPrice.filter((price) => price !== 0); // price 0인 경우 제거 const defaultPrice = existSellingPrice[0]; - const priceChangeVariation = existSellingPrice[1] - existSellingPrice[0]; - - console.log(typeof priceChangeVariation); + const priceInterval = existSellingPrice[1] - existSellingPrice[0]; // 초기 설정값 세팅 useEffect(() => { @@ -30,11 +28,11 @@ const PriceSetting = (props: OwnProps) => { // 거래가 증가/감소 const handlePlusOrderPrice = () => { - dispatch(plusStockOrderPrice(priceChangeVariation)); + dispatch(plusStockOrderPrice(priceInterval)); }; const handleMinusOrderPrice = () => { - dispatch(minusStockOrderPrice(priceChangeVariation)); + dispatch(minusStockOrderPrice(priceInterval)); }; return ( diff --git a/client/src/components/StockOrderSection/StockOrderSetting.tsx b/client/src/components/StockOrderSection/StockOrderSetting.tsx index e3f9c265..b4760022 100644 --- a/client/src/components/StockOrderSection/StockOrderSetting.tsx +++ b/client/src/components/StockOrderSection/StockOrderSetting.tsx @@ -1,4 +1,3 @@ -import { useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import useGetStockInfo from "../../hooks/useGetStockInfo"; import { orderTypeBuying, orderTypeSelling } from "../../reducer/StockOrderType-Reducer"; @@ -14,14 +13,11 @@ const orderType01: string = "매수"; const orderType02: string = "매도"; const StockOrderSetting = () => { - const stockOrderType = useSelector((state: StateProps) => state.stockOrderType); const dispatch = useDispatch(); - + const orderType = useSelector((state: StateProps) => state.stockOrderType); const companyId = useSelector((state: StateProps) => state.companyId); const { stockInfo, stockInfoLoading, stockInfoError } = useGetStockInfo(companyId); - const [orderVolume, setOrderVolume] = useState(0); - if (stockInfoLoading) { return <>; } @@ -41,17 +37,17 @@ const StockOrderSetting = () => { return (
- + {orderType01} - + {orderType02}
- - + +
); }; @@ -60,12 +56,12 @@ export default StockOrderSetting; // 매수/매도 탭 전환 시 하단에 시각화 되는 선 const OrderTypeChangeEffetLine = () => { - const stockOrderType = useSelector((state: StateProps) => state.stockOrderType); + const orderType = useSelector((state: StateProps) => state.stockOrderType); return ( - - - + + + ); diff --git a/client/src/components/StockOrderSection/StockPriceList.tsx b/client/src/components/StockOrderSection/StockPriceList.tsx index 0bb5d618..80c82249 100644 --- a/client/src/components/StockOrderSection/StockPriceList.tsx +++ b/client/src/components/StockOrderSection/StockPriceList.tsx @@ -7,8 +7,8 @@ import { StateProps } from "../../models/stateProps"; import StockPrice from "./StockPrice"; const StockPriceList = () => { - const stockOrderType = useSelector((state: StateProps) => state.stockOrderType); const companyId = useSelector((state: StateProps) => state.companyId); + const stockOrderType = useSelector((state: StateProps) => state.stockOrderType); const { stockInfo, stockInfoLoading, stockInfoError } = useGetStockInfo(companyId); if (stockInfoLoading) { diff --git a/client/src/components/StockOrderSection/VolumeSetteing.tsx b/client/src/components/StockOrderSection/VolumeSetteing.tsx index a5188074..50e48e89 100644 --- a/client/src/components/StockOrderSection/VolumeSetteing.tsx +++ b/client/src/components/StockOrderSection/VolumeSetteing.tsx @@ -1,7 +1,8 @@ import { useEffect } from "react"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import { styled } from "styled-components"; import { StateProps } from "../../models/stateProps"; +import { setStockOrderVolume, plusStockOrderVolume, minusStockOrderVolume } from "../../reducer/StockOrderVolume-Reducer"; const volumeSettingTitle: string = "수량"; const maximumVolumeText01: string = "최대"; @@ -17,26 +18,29 @@ const percentageUnit: string = "%"; const dummyMoney: number = 10000000; const dummyholdingStock = 10; -const VolumeSetting = (props: OwnProps) => { - const { orderVolume, setOrderVolume } = props; +const VolumeSetting = () => { + const dispatch = useDispatch(); const orderType = useSelector((state: StateProps) => state.stockOrderType); const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice); + const orderVolume = useSelector((state: StateProps) => state.stockOrderVolume); + const maximumBuyingVolume = Math.trunc(dummyMoney / orderPrice); const handlePlusOrderVolume = () => { // 매수 -> 증가 버튼 클릭 시, 최대 구매수량 보다 낮으면 개수 1증가 if (!orderType) { - orderVolume < maximumBuyingVolume && setOrderVolume((previousState: number) => previousState + 1); + orderVolume < maximumBuyingVolume && dispatch(plusStockOrderVolume()); } // 매도 -> 증가 버튼 클릭 시, 보유 주식수량 보다 낮으면 개수 1증가 if (orderType) { - orderVolume < dummyholdingStock && setOrderVolume((previousState: number) => previousState + 1); + orderVolume < dummyholdingStock && dispatch(plusStockOrderVolume()); } }; const handleMinusOrderVolume = () => { if (0 < orderVolume) { - setOrderVolume((previousState: number) => previousState - 1); + // setOrderVolume((previousState: number) => previousState - 1); + dispatch(minusStockOrderVolume()); } }; @@ -44,29 +48,20 @@ const VolumeSetting = (props: OwnProps) => { // 매수 -> percentage 버튼 클릭 시, 최대 구매수량 내에서 계산 if (!orderType) { const orderVolume = Math.trunc(maximumBuyingVolume * (volumePerentage / 100)); - setOrderVolume((previousState) => { - previousState = orderVolume; - return previousState; - }); + dispatch(setStockOrderVolume(orderVolume)); } // 매도 -> percentage 버튼 클릭 시, 보유 주식수량 내에서 계산 if (orderType) { const orderVolume = Math.trunc(dummyholdingStock * (volumePerentage / 100)); - setOrderVolume((previousState) => { - previousState = orderVolume; - return previousState; - }); + dispatch(setStockOrderVolume(orderVolume)); } }; // 지정가 증가 -> (현재 주문수량 > 최대 주문가능 수량)일 경우 -> 현재 주문수량을 최대 주문수량으로 변경 useEffect(() => { if (maximumBuyingVolume < orderVolume) { - setOrderVolume((previousState) => { - previousState = maximumBuyingVolume; - return previousState; - }); + dispatch(setStockOrderVolume(maximumBuyingVolume)); } }, [maximumBuyingVolume]); @@ -116,12 +111,6 @@ const VolumeSetting = (props: OwnProps) => { export default VolumeSetting; -// type 정의 -interface OwnProps { - orderVolume: number; - setOrderVolume: (updateFunction: (previousState: number) => number) => void; -} - // component 생성 const Container = styled.div` width: 100%; diff --git a/client/src/models/stateProps.ts b/client/src/models/stateProps.ts index 56d3fca1..fac7d932 100644 --- a/client/src/models/stateProps.ts +++ b/client/src/models/stateProps.ts @@ -5,4 +5,5 @@ export interface StateProps { expandScreen: { left: boolean; right: boolean }; stockOrderSet: boolean; companyId: number; + stockOrderVolume: number; } diff --git a/client/src/reducer/StockOrderVolume-Reducer.ts b/client/src/reducer/StockOrderVolume-Reducer.ts new file mode 100644 index 00000000..e9e0284e --- /dev/null +++ b/client/src/reducer/StockOrderVolume-Reducer.ts @@ -0,0 +1,16 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState: number = 0; + +const stockOrderVolumeSlice = createSlice({ + name: "stockOrderVolume", + initialState: initialState, + reducers: { + setStockOrderVolume: (_, action) => action.payload, + plusStockOrderVolume: (state) => state + 1, + minusStockOrderVolume: (state) => state - 1, + }, +}); + +export const { setStockOrderVolume, plusStockOrderVolume, minusStockOrderVolume } = stockOrderVolumeSlice.actions; +export const stockOrderVolumeReducer = stockOrderVolumeSlice.reducer; diff --git a/client/src/store/config.ts b/client/src/store/config.ts index f4cfe78b..62188daa 100644 --- a/client/src/store/config.ts +++ b/client/src/store/config.ts @@ -5,6 +5,7 @@ import { expandScreenReducer } from "../reducer/ExpandScreen-Reducer"; import { stockOrderSetReducer } from "../reducer/StockOrderSet-Reducer"; import { companyIdReducer } from "../reducer/CompanyId-Reducer"; import memberInfoReducer from "../reducer/member/memberInfoSlice"; +import { stockOrderVolumeReducer } from "../reducer/StockOrderVolume-Reducer"; const store = configureStore({ reducer: { @@ -14,6 +15,7 @@ const store = configureStore({ stockOrderSet: stockOrderSetReducer, companyId: companyIdReducer, memberInfo: memberInfoReducer, + stockOrderVolume: stockOrderVolumeReducer, }, });