From bf8dbffd1561bd8fe5d00e699a3d7160eb9bec5a Mon Sep 17 00:00:00 2001 From: truthwing Date: Wed, 5 Mar 2025 15:44:17 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=B2=AB=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20store=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/page.tsx | 6 +- apps/wr/app/publicReuseFaciltyInsert/page.tsx | 138 ++++-------------- apps/wr/app/store/index.tsx | 46 ++++++ .../store/publicReuseFaciltyInsert/index.tsx | 97 ++++++++++++ apps/wr/app/store/store.tsx | 12 ++ 5 files changed, 185 insertions(+), 114 deletions(-) create mode 100644 apps/wr/app/store/index.tsx create mode 100644 apps/wr/app/store/publicReuseFaciltyInsert/index.tsx create mode 100644 apps/wr/app/store/store.tsx diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index a3c2e4c7a..d9c5d3f0e 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -1,12 +1,12 @@ import PublicReuseFaciltyInsert from './publicReuseFaciltyInsert/page'; +import { StoreProvider } from './store'; export default function Home() { - - - return ( + + ); } diff --git a/apps/wr/app/publicReuseFaciltyInsert/page.tsx b/apps/wr/app/publicReuseFaciltyInsert/page.tsx index f5e565fd3..18434ac92 100644 --- a/apps/wr/app/publicReuseFaciltyInsert/page.tsx +++ b/apps/wr/app/publicReuseFaciltyInsert/page.tsx @@ -1,115 +1,20 @@ -import {UiTable} from '@common/business_components'; -import { TableRow } from '@common/components'; -import { TableHead } from '@common/components'; +"use client"; +import { UiTable } from '@common/business_components'; +import { Button, TableHead, TableRow } from '@common/components'; +import { useEffect } from 'react'; +import { useWrStore } from '../store'; +import type { TableUpperProps } from '../store/publicReuseFaciltyInsert'; -interface TableUpperProps { - id: string; - title: string; - upName : string; - upSequnce: number; -} - -const publicReuseFacility = [ - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - reuse: "Y", - register: "Y" - }, - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - reuse: "Y", - register: "Y" - }, - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - reuse: "Y", - register: "Y" - }, - -] - -const publicReuseFacilityUper = [ - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - reuse: "Y", - register: "Y" - }, - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - reuse: "Y", - register: "Y" - }, - { - sido: "서울", - sigungo: "강남구", - facilityName: "난지", - location: "경기도 고양시 덕양구 대차로 4가", - locationgubun: "500", - facilityCapacity: "800,000", - yn: "Y", - authoDay: "2012", - area:"123" - }, - ] - - - -const headList = [ - { id: "sido", title: "시도" }, - { id: "sigungo", title: "시군구" }, - { id: "facilityName", title: "시설명" }, - { id: "location", title: "위치" }, - { id: "locationgubun", title: "지역구분" }, - { id: "facilityCapacity", title: "시설용량" }, - { id: "reuse", title: '재이용여부' }, - { id: "register", title: '등록여부' }]; - - - - const upHeadList = [ - { id: "sido", title: "시도" }, - { id: "sigungo", title: "시군구" }, - { id: "facilityName", title: "시설명" }, - { id: "location", title: "위치" }, - { id: "locationgubun", title: "지역구분" }, - { id: "facilityCapacity", title: "시설용량" }, - { id: "yn", title: '여부', upName:'upChangeRe' , upSequnce:1 }, - { id: "authoDay", title: '허가일',upName:'upChangeRe', upSequnce:2 }, - { id: "area", title: '면적' ,upName:'upChangeRe',upSequnce:3 }]; const headMakeColSpan = (upHeadList: any) => { return ( <> { upHeadList.map((head: TableUpperProps) => - (head.upName === 'upChangeRe'&& head.upSequnce=== 1?{'중축 개축 증축 '}: - head.upSequnce> 1?null:{head.title}))} + (!head.upSequnce?null: + head.upName === 'upChangeRe'&& head.upSequnce=== 1?{'중축 개축 증축 '}: + head.upSequnce > 1?null:{head.title}))} {upHeadList.map((head: TableUpperProps) => @@ -118,15 +23,26 @@ const headList = [ ) } - - - export default function PublicReuseFaciltyInsert() { - +export default function PublicReuseFaciltyInsert() { + const { isInit, upHeadList, publicReuseFacilityUper, decrementList} = useWrStore((state) => state); const nodeList= headMakeColSpan(upHeadList); const total = 100; - return (
- -
+ //sample + useEffect(() => { + if(!isInit) + decrementList(); + }, [isInit]); + + return ( + <> + +
+ {/* sample store */} + +
+ ); } diff --git a/apps/wr/app/store/index.tsx b/apps/wr/app/store/index.tsx new file mode 100644 index 000000000..6578fa47d --- /dev/null +++ b/apps/wr/app/store/index.tsx @@ -0,0 +1,46 @@ +'use client' + +import { type ReactNode, createContext, useContext, useRef } from 'react' +import { useStore } from 'zustand' +import { type WrStore, StoreZus } from './store' + + +export type StoreApi = ReturnType + +export const StoreContext = createContext( + undefined, +) + +export interface StoreProviderProps { + children: ReactNode +} + +export const StoreProvider = ({ + children, +}: StoreProviderProps) => { + const storeRef = useRef(null) + console.log("StoreProvider"); + + if (!storeRef.current) { + storeRef.current = StoreZus() + } + + return ( + + {children} + + ) +} + +export const useWrStore = ( + selector: (store: WrStore) => T, +): T => { + const storeContext = useContext(StoreContext) + console.log("useStore", storeContext); + + if (!storeContext) { + throw new Error(`useStore must be used within StoreProvider`) + } + + return useStore(storeContext, selector) +} \ No newline at end of file diff --git a/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx b/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx new file mode 100644 index 000000000..15b252b24 --- /dev/null +++ b/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx @@ -0,0 +1,97 @@ +export type TableUpperProps = { + id: string; + title: string; + upName?: string; + upSequnce?: number; +} +type PublicReuseFacility = { + sido: string, + sigungo: string, + facilityName: string, + location: string, + locationgubun: string, + facilityCapacity: string, + yn?: string, + authoDay?: string, + area?: string, + reuse?: string, + register?: string +} +const upHeadList:TableUpperProps[] = [ + { id: "sido", title: "시도"}, + { id: "sigungo", title: "시군구"}, + { id: "facilityName", title: "시설명"}, + { id: "location", title: "위치"}, + { id: "locationgubun", title: "지역구분"}, + { id: "facilityCapacity", title: "시설용량"}, + { id: "yn", title: '여부', upName:'upChangeRe' , upSequnce:1 }, + { id: "authoDay", title: '허가일',upName:'upChangeRe', upSequnce:2 }, + { id: "area", title: '면적' ,upName:'upChangeRe',upSequnce:3 }]; + +const publicReuseFacilityUper:PublicReuseFacility[] = [ + { + sido: "서울", + sigungo: "강남구", + facilityName: "난지", + location: "경기도 고양시 덕양구 대차로 4가", + locationgubun: "500", + facilityCapacity: "800,000", + reuse: "Y", + register: "Y" + }, + { + sido: "서울", + sigungo: "강남구", + facilityName: "난지", + location: "경기도 고양시 덕양구 대차로 4가", + locationgubun: "500", + facilityCapacity: "800,000", + reuse: "Y", + register: "Y" + }, + { + sido: "서울", + sigungo: "강남구", + facilityName: "난지", + location: "경기도 고양시 덕양구 대차로 4가", + locationgubun: "500", + facilityCapacity: "800,000", + yn: "Y", + authoDay: "2012", + area:"123" + }, +] + +export type tableState = { + isInit: boolean; + upHeadList: TableUpperProps[]; + publicReuseFacilityUper: PublicReuseFacility[]; +} +type tableActions = { + decrementList: () => void +} + +export type tableType = tableState & tableActions; + +export const tableStateExport:tableState= { + isInit:false, + upHeadList: upHeadList, + publicReuseFacilityUper: publicReuseFacilityUper, +} +export const tableActionsExport:(set:any)=>tableActions=(set: any) => { + + console.log("tableActionsExport"); + return { + decrementList:()=>set( + (state:tableState) => { + + console.log("tableActionsExport", state); + return ( + { + upHeadList: state.upHeadList, + publicReuseFacilityUper: + state.publicReuseFacilityUper.slice(0, state.publicReuseFacilityUper.length - 1) + })} + ) + } +} diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx new file mode 100644 index 000000000..8ba4ea81b --- /dev/null +++ b/apps/wr/app/store/store.tsx @@ -0,0 +1,12 @@ +import { createStore } from 'zustand/vanilla'; +import { tableActionsExport, tableStateExport, type tableState, type tableType } from './publicReuseFaciltyInsert/index'; +export type WrStore = tableType; +export const StoreZus = (initState: tableState = tableStateExport) => { + return createStore()((set) => { + return { + ...initState, + ...tableActionsExport(set) + } + }) +} +//store 등록하는 부분 \ No newline at end of file From 9f71e5527c4823c164e17cb7a352e18983b7ff85 Mon Sep 17 00:00:00 2001 From: truthwing Date: Wed, 5 Mar 2025 15:48:05 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=83=80=EC=9D=B4=ED=8B=80=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EB=A1=9C=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/publicReuseFaciltyInsert/page.tsx | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/wr/app/publicReuseFaciltyInsert/page.tsx b/apps/wr/app/publicReuseFaciltyInsert/page.tsx index 18434ac92..577440b8c 100644 --- a/apps/wr/app/publicReuseFaciltyInsert/page.tsx +++ b/apps/wr/app/publicReuseFaciltyInsert/page.tsx @@ -8,20 +8,19 @@ import type { TableUpperProps } from '../store/publicReuseFaciltyInsert'; - const headMakeColSpan = (upHeadList: any) => { - return ( <> - { - upHeadList.map((head: TableUpperProps) => - (!head.upSequnce?null: - head.upName === 'upChangeRe'&& head.upSequnce=== 1?{'중축 개축 증축 '}: - head.upSequnce > 1?null:{head.title}))} - - - {upHeadList.map((head: TableUpperProps) => - (head.upName === 'upChangeRe'?{head.title}:null))} - - ) - } +const headMakeColSpan = (upHeadList: any) => { + return ( <> + { + upHeadList.map((head: TableUpperProps) => + (!head.upSequnce?{head.title}: + head.upName === 'upChangeRe'&& head.upSequnce=== 1?{'중축 개축 증축 '}:null))} + + + {upHeadList.map((head: TableUpperProps) => + (head.upName === 'upChangeRe'?{head.title}:null))} + + ) +} export default function PublicReuseFaciltyInsert() { const { isInit, upHeadList, publicReuseFacilityUper, decrementList} = useWrStore((state) => state); From 54e6ae34437548bfe14d094c277e2a8394d3afe1 Mon Sep 17 00:00:00 2001 From: truthwing Date: Wed, 5 Mar 2025 15:53:10 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=ED=83=80=EC=9E=85=EC=97=90=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=EA=B0=80=20=EC=97=86=EA=B2=8C=EB=81=94=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=99=84=EB=A3=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business_components/src/ui/table/index.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index 17360af12..058d28673 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -1,21 +1,19 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; +import { type TableUpperProps } from '../../../../../../apps/wr/app/store/publicReuseFaciltyInsert/index'; import UiPageNations from "./uiPageNations"; interface UiTableProps { headName: string; - publicReuseFacility: any[]; - headlist: { id: string; title: string; }[]; + publicReuseFacility: { [key: string]: string | number | boolean }[]; + headlist: TableUpperProps[]; pageSize: number; total: number; children: React.ReactNode|undefined; } -export function UiTable(UiTableProps: UiTableProps) { - const { publicReuseFacility, headlist,pageSize , total, children,headName} = UiTableProps; +export function UiTable({ publicReuseFacility, headlist,pageSize , total, children,headName}: UiTableProps) { const cur = 1; - - return ( <>

{headName}

@@ -29,7 +27,7 @@ export function UiTable(UiTableProps: UiTableProps) { - {publicReuseFacility.map((el: any,index) => ( + {publicReuseFacility.map((el: { [key: string]: string | number | boolean },index) => ( {headlist.map((head) => ( {el[head.id]} From 58d5175ee56e307d62f3984f09bf94f79ce6a5a7 Mon Sep 17 00:00:00 2001 From: truthwing Date: Wed, 5 Mar 2025 16:31:36 +0900 Subject: [PATCH 4/4] =?UTF-8?q?store=20=EC=82=AC=EC=9A=A9=20=EB=B0=A9?= =?UTF-8?q?=EB=B2=95=20md=20=EC=9E=91=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/store/index.tsx | 5 - .../store/publicReuseFaciltyInsert/index.tsx | 4 - apps/wr/app/store/readme.md | 121 ++++++++++++++++++ 3 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 apps/wr/app/store/readme.md diff --git a/apps/wr/app/store/index.tsx b/apps/wr/app/store/index.tsx index 6578fa47d..1b759c30e 100644 --- a/apps/wr/app/store/index.tsx +++ b/apps/wr/app/store/index.tsx @@ -19,12 +19,9 @@ export const StoreProvider = ({ children, }: StoreProviderProps) => { const storeRef = useRef(null) - console.log("StoreProvider"); - if (!storeRef.current) { storeRef.current = StoreZus() } - return ( {children} @@ -36,8 +33,6 @@ export const useWrStore = ( selector: (store: WrStore) => T, ): T => { const storeContext = useContext(StoreContext) - console.log("useStore", storeContext); - if (!storeContext) { throw new Error(`useStore must be used within StoreProvider`) } diff --git a/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx b/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx index 15b252b24..f4f539a3f 100644 --- a/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx +++ b/apps/wr/app/store/publicReuseFaciltyInsert/index.tsx @@ -79,13 +79,9 @@ export const tableStateExport:tableState= { publicReuseFacilityUper: publicReuseFacilityUper, } export const tableActionsExport:(set:any)=>tableActions=(set: any) => { - - console.log("tableActionsExport"); return { decrementList:()=>set( (state:tableState) => { - - console.log("tableActionsExport", state); return ( { upHeadList: state.upHeadList, diff --git a/apps/wr/app/store/readme.md b/apps/wr/app/store/readme.md new file mode 100644 index 000000000..0710aa69b --- /dev/null +++ b/apps/wr/app/store/readme.md @@ -0,0 +1,121 @@ +# Zustand store +## Zustand 등록방법 +**-- index.tsx --** +### context 등록 +기본적으로 createContext를 통해 react에 context를 생성해서 react에서 사용할 수 있도록 해야함. +``` js +//StoreZus는 내부적으로 사용하기 위한 store파일에서 따로 생성함. +export type StoreApi = ReturnType +//react에서 사용하기 위한 context 생성. +export const StoreContext = createContext( + undefined, +) +``` + +### component로 작성 +등록된 context를 component화 시키기 위한 작업 +```js +//외부에서 호출시 형태로 호출. +//app이나 home에서 전체적인 사용이 되도록 작성해야함. +export const StoreProvider = ({ + children, +}: StoreProviderProps) => { + const storeRef = useRef(null) + if (!storeRef.current) { + //StoreZus는 store.tsx를 봐야함. + storeRef.current = StoreZus() + } + return ( + + {children} + + ) +} +``` + +### store 등록 +react에서 사용하는 store에 현재 context 등록 +```js +export const useWrStore = ( + selector: (store: WrStore) => T, +): T => { + const storeContext = useContext(StoreContext) + if (!storeContext) { + throw new Error(`useStore must be used within StoreProvider`) + } + + return useStore(storeContext, selector) +} +``` + +## Zustand 사용방법 +**-- store.tsx, 폴더별 index.tsx --** +### 기본 store 생성 +index.tsx의 context에 사용되는 StoreZus를 추가하여 사용됨. + +외부에서 생성된 state, actions를 사용 가능한 구조 +```js +import { createStore } from 'zustand/vanilla'; +import { tableActionsExport, tableStateExport, type tableState, type tableType } from './publicReuseFaciltyInsert/index';//외부 파일 위치. +export type WrStore = tableType;//typescript이므로 사용되는 스크립트를 type1 & type2 형식으로 넣어야함. +//index.tsx에서 사용하는 store 생성. +export const StoreZus = (initState: tableState = tableStateExport) => { + return createStore()((set) => { + return { + //아래에서 사용하는 state & actions은 외부 폴더에서 가져다가 사용. + ...initState,//외부에 있는 기본 초기값 state + ...tableActionsExport(set)//외부에 있는 actions + } + }) +} +``` +### 외부 스토어 작성 방법 +외부 스토어는 export를 어떻게 할건지만 정하면됨. + +사용하는 store.tsx에서 import를 받기만 하면 사용가능. +#### 타입을 외부로 빼는 방법 +```js +export type tableState = { + isInit: boolean; + upHeadList: TableUpperProps[]; + publicReuseFacilityUper: PublicReuseFacility[]; +} +type tableActions = { + decrementList: () => void +} + +export type tableType = tableState & tableActions; +``` +#### 초기값 state를 외부로 빼는 방법 +```js +export const tableStateExport:tableState= { + isInit:false, + upHeadList: upHeadList, + publicReuseFacilityUper: publicReuseFacilityUper, +} +``` +#### actions를 외부로 빼는 방법 +```js +//tableActionsExport를 import 받아서 실행하여 return 된 값을 사용 +export const tableActionsExport:(set:any)=>tableActions= +//set을 통해 react store에 등록 +(set: any) => { + return { + //decrementList Object 형태로 전달 + decrementList: + //set 함수를 실행해서 react store에 등록 + ()=>set( + // store에 등록되는 함수 구조를 가지고 있음. + (state:tableState) => { + //actions 실질적인 로직 작성하는 곳. + return ( + { + upHeadList: state.upHeadList, + publicReuseFacilityUper: + state.publicReuseFacilityUper.slice(0, state.publicReuseFacilityUper.length - 1) + })} + ) + } +} +``` +