Merge remote-tracking branch 'origin/iipbs/wr/store' into iipbs/wr/dev

This commit is contained in:
leedj312
2025-03-05 16:55:10 +09:00
7 changed files with 284 additions and 118 deletions
+3 -3
View File
@@ -1,12 +1,12 @@
import PublicReuseFaciltyInsert from './publicReuseFaciltyInsert/page';
import { StoreProvider } from './store';
export default function Home() {
return (
<StoreProvider>
<PublicReuseFaciltyInsert />
</StoreProvider>
);
}
+8 -107
View File
@@ -9,113 +9,18 @@ import { Input, TableRow } from '@common/components';
import { TableHead } from '@common/components';
import { FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from "@common/business_components/ui/form/lib/form";
import Style from "../style/PublicReuseFaciltyInsert.module.css";
interface TableUpperProps {
id: string;
title: string|undefined;
upName : string|undefined;
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"
},
]
import { useWrStore } from '../store';
import type { TableUpperProps } from '../store/publicReuseFaciltyInsert';
/*
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: "시도" , upName:'no',upSequnce:1 },
{ id: "sigungo", title: "시군구" , upName:'no', upSequnce:1 },
{ id: "facilityName", title: "시설명" , upName:'no', upSequnce:1 },
{ id: "location", title: "위치" , upName:'no',upSequnce:1 },
{ id: "locationgubun", title: "지역구분" ,upName:'no', upSequnce:1 },
{ id: "facilityCapacity", title: "시설용량" , upName:'no',upSequnce:1 },
{ id: "yn", title: '여부', upName:'upChangeRe' , upSequnce:1 },
{ id: "authoDay", title: '허가일',upName:'upChangeRe', upSequnce:2 },
{ id: "area", title: '면적' ,upName:'upChangeRe',upSequnce:3 }];
const headMakeColSpan = (upHeadList: TableUpperProps[]) => {
return ( <>
<TableRow>{
upHeadList.map((head: TableUpperProps) =>
(head.upName === 'upChangeRe'&& head.upSequnce=== 1?<TableHead key={head.id+head.upSequnce} rowSpan={1} colSpan={3}>{'중축 개축 증축 '}</TableHead>:
head.upSequnce> 1?null:<TableHead rowSpan={2}key={head.id}>{head.title}</TableHead>))}
(!head.upSequnce?<TableHead rowSpan={2}key={head.id}>{head.title}</TableHead>:
head.upName === 'upChangeRe'&& head.upSequnce=== 1?<TableHead key={head.id} rowSpan={1} colSpan={3}>{'중축 개축 증축 '}</TableHead>:null))}
</TableRow>
<TableRow>
{upHeadList.map((head: TableUpperProps) =>
@@ -127,13 +32,8 @@ const headList = [
export default function PublicReuseFaciltyInsert() {
const { upHeadList, publicReuseFacilityUper} = useWrStore((state) => state);
const nodeList= headMakeColSpan(upHeadList);
const total = 100;
@@ -191,6 +91,7 @@ const form = useForm<z.infer<typeof formSchema>>({
</div>
</>
);
}
)}
+41
View File
@@ -0,0 +1,41 @@
'use client'
import { type ReactNode, createContext, useContext, useRef } from 'react'
import { useStore } from 'zustand'
import { type WrStore, StoreZus } from './store'
export type StoreApi = ReturnType<typeof StoreZus>
export const StoreContext = createContext<StoreApi | undefined>(
undefined,
)
export interface StoreProviderProps {
children: ReactNode
}
export const StoreProvider = ({
children,
}: StoreProviderProps) => {
const storeRef = useRef<StoreApi>(null)
if (!storeRef.current) {
storeRef.current = StoreZus()
}
return (
<StoreContext.Provider value={storeRef.current}>
{children}
</StoreContext.Provider>
)
}
export const useWrStore = <T,>(
selector: (store: WrStore) => T,
): T => {
const storeContext = useContext(StoreContext)
if (!storeContext) {
throw new Error(`useStore must be used within StoreProvider`)
}
return useStore(storeContext, selector)
}
@@ -0,0 +1,93 @@
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) => {
return {
decrementList:()=>set(
(state:tableState) => {
return (
{
upHeadList: state.upHeadList,
publicReuseFacilityUper:
state.publicReuseFacilityUper.slice(0, state.publicReuseFacilityUper.length - 1)
})}
)
}
}
+121
View File
@@ -0,0 +1,121 @@
# Zustand store
## Zustand 등록방법
**-- index.tsx --**
### context 등록
기본적으로 createContext를 통해 react에 context를 생성해서 react에서 사용할 수 있도록 해야함.
``` js
//StoreZus는 내부적으로 사용하기 위한 store파일에서 따로 생성함.
export type StoreApi = ReturnType<typeof StoreZus>
//react에서 사용하기 위한 context 생성.
export const StoreContext = createContext<StoreApi | undefined>(
undefined,
)
```
### component로 작성
등록된 context를 component화 시키기 위한 작업
```js
//외부에서 호출시 <StoreProvider> 형태로 호출.
//app이나 home에서 전체적인 사용이 되도록 작성해야함.
export const StoreProvider = ({
children,
}: StoreProviderProps) => {
const storeRef = useRef<StoreApi>(null)
if (!storeRef.current) {
//StoreZus는 store.tsx를 봐야함.
storeRef.current = StoreZus()
}
return (
<StoreContext.Provider value={storeRef.current}>
{children}
</StoreContext.Provider>
)
}
```
### store 등록
react에서 사용하는 store에 현재 context 등록
```js
export const useWrStore = <T,>(
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<WrStore>()((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)
})}
)
}
}
```
+12
View File
@@ -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<WrStore>()((set) => {
return {
...initState,
...tableActionsExport(set)
}
})
}
//store 등록하는 부분
@@ -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 (
<>
<p>{headName}</p>
@@ -29,7 +27,7 @@ export function UiTable(UiTableProps: UiTableProps) {
</TableHeader>
<TableBody>
{publicReuseFacility.map((el: any,index) => (
{publicReuseFacility.map((el: { [key: string]: string | number | boolean },index) => (
<TableRow key={index+"row"} >
{headlist.map((head) => (
<TableCell key={head.id+index}>{el[head.id]}</TableCell>