-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/softeerbootcamp4th/Team3-Ca…
- Loading branch information
Showing
21 changed files
with
335 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
interface Action { | ||
type: string; | ||
actionName: string; | ||
payload?: object; | ||
} | ||
|
||
export default Action |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import useBind from "../Hooks/Binding.tsx"; | ||
import { action, initCountState, countReducer } from "./CountWorkFlow.tsx"; | ||
import store from "../Store.tsx"; | ||
|
||
const Counter = () => { | ||
const state = useBind(initCountState, countReducer); | ||
|
||
function temp1() { | ||
store.dispatch(action.countUp()); | ||
} | ||
|
||
function temp2() { | ||
store.dispatch(action.getText("sdsd")); | ||
store.dispatch(action.countDown()); | ||
} | ||
|
||
return ( | ||
<div> | ||
<h1>{state.text}</h1> | ||
<div>{state.count}</div> | ||
<br></br> | ||
<button onClick={temp1}>up</button> | ||
<button onClick={temp2}>down</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Counter; |
64 changes: 64 additions & 0 deletions
64
Caecae/src/Shared/Hyundux/Example_Counter/CountWorkFlow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { createState } from "../State"; | ||
import { makePayLoad } from "../Util/StoreUtil"; | ||
import Reducer from "../Reducer"; | ||
import Action from "../Actions"; | ||
|
||
const WORKFLOW_NAME = "Count"; | ||
|
||
// state type | ||
interface CountPayLoad { | ||
count: number; | ||
text: string; | ||
} | ||
|
||
const initCountState = createState<CountPayLoad>(WORKFLOW_NAME, { | ||
count: 0, | ||
text: "helloWorld", | ||
}); | ||
|
||
// define reducer | ||
const countReducer: Reducer<CountPayLoad> = { | ||
type: WORKFLOW_NAME, | ||
reducer: async function reducer(state, action) { | ||
const payLoad = state.payload; | ||
switch (action.actionName) { | ||
case "countUp": | ||
return makePayLoad(state, { count: payLoad.count + 1 }); | ||
case "countDown": | ||
return makePayLoad(state, { count: payLoad.count - 1 }); | ||
case "getText": { | ||
const actionPayLoad = (action.payload || {}) as { text: string }; | ||
return makePayLoad(state, { text: actionPayLoad.text }); | ||
} | ||
default: | ||
return state; | ||
} | ||
}, | ||
}; | ||
|
||
// actions | ||
const action = { | ||
countUp: (): Action => { | ||
return { | ||
type: WORKFLOW_NAME, | ||
actionName: "countUp", | ||
}; | ||
}, | ||
countDown: (): Action => { | ||
return { | ||
type: WORKFLOW_NAME, | ||
actionName: "countDown", | ||
}; | ||
}, | ||
getText: (text: string): Action => { | ||
return { | ||
type: WORKFLOW_NAME, | ||
actionName: "getText", | ||
payload: { | ||
text: text, | ||
}, | ||
}; | ||
}, | ||
}; | ||
|
||
export { action, initCountState, countReducer }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { useState } from 'react'; | ||
import HState from '../State'; | ||
import store from '../Store'; | ||
import Reducer from '../Reducer'; | ||
|
||
|
||
function useBind<PayLoad>(initialState: HState<PayLoad>, reducer: Reducer<PayLoad>): PayLoad { | ||
const [state, setState] = useState<HState<PayLoad>>(initialState); | ||
store.subscribe(state, reducer, (newState) => { | ||
setState(newState) | ||
}); | ||
|
||
return state.payload; | ||
} | ||
|
||
export default useBind; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Action from "./Actions"; | ||
import State from "./State"; | ||
|
||
interface Reducer<PayLoad> { | ||
type: string; | ||
reducer: (state: State<PayLoad>, action: Action) => Promise<State<PayLoad>>; | ||
} | ||
|
||
export default Reducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
interface State<T> { | ||
type: string; | ||
payload: T; | ||
} | ||
|
||
function createState<PayLoad>(type: string, payload: PayLoad): State<PayLoad> { | ||
return { | ||
type: type, | ||
payload: payload | ||
} | ||
} | ||
|
||
export { createState } | ||
export default State |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import Action from "./Actions"; | ||
import State from "./State"; | ||
import Reducer from "./Reducer"; | ||
import removeFirst from "./Util/RemoveFirst"; | ||
import replaceFirst from "./Util/ReplaceFirst"; | ||
|
||
const store: { | ||
states: State<unknown>[], | ||
reducers: Reducer<unknown>[], | ||
subscribe: <PayLoad>(initState: State<PayLoad>, reducer: Reducer<PayLoad>, cb: (state: State<PayLoad>) => void) => void, | ||
dispatch: (action: Action) => void, | ||
publish: <PayLoad>(state: State<PayLoad>) => void, | ||
subscribeList: Map<string, <PayLoad>(state: State<PayLoad>) => void>, | ||
} = { | ||
states: [], | ||
reducers: [], | ||
subscribeList: new Map(), | ||
dispatch: async function (action) { | ||
const reducer = this.reducers.filter(reducer => reducer.type == action.type)[0].reducer | ||
const { removed, newArray } = removeFirst(this.states, (state) => state.type == action.type) | ||
const newState = await reducer(removed, action); | ||
// 여기서 모든것을 바로 state를 적용하는것이 아니라 이게 다른 state도 propagation하는지도 확인해야함 | ||
this.states = [...newArray, newState]; | ||
this.publish(newState); | ||
}, | ||
publish: function (state) { | ||
const publishedCallBack = this.subscribeList.get(state.type); | ||
if (publishedCallBack !== undefined) { | ||
publishedCallBack(state); | ||
} | ||
}, | ||
subscribe: function <PayLoad>(state: State<PayLoad>, reducer: Reducer<PayLoad>, cb: (state: State<PayLoad>) => void) { | ||
this.states = replaceFirst(this.states, state, (element) => element.type == state.type) | ||
this.reducers = replaceFirst(this.reducers, reducer as Reducer<unknown>, (element) => element.type == state.type) | ||
this.subscribeList.set(state.type, cb as (state: State<unknown>) => void); | ||
} | ||
} | ||
|
||
export default store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
function removeFirst<T>(arr: T[], predicate: (item: T) => boolean): { removed: T, newArray: T[] } { | ||
const index = arr.findIndex(predicate); | ||
|
||
const removed = arr[index]; | ||
const newArray = [...arr.slice(0, index), ...arr.slice(index + 1)]; | ||
|
||
return { removed, newArray }; | ||
} | ||
|
||
export default removeFirst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
function replaceFirst<Element>( | ||
array: Element[], | ||
newItem: Element, | ||
condition: (item: Element) => boolean, | ||
): Element[] { | ||
const index = array.findIndex(condition); | ||
if (index !== -1) { | ||
const newArray = [...array]; | ||
newArray[index] = newItem; | ||
return newArray; | ||
} | ||
return [...array, newItem]; | ||
} | ||
|
||
export default replaceFirst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import State from "../State"; | ||
|
||
export function makePayLoad<PayLoad>(originState: State<PayLoad>, payload: object): State<PayLoad> { | ||
return { ...originState, payload: { ...originState.payload, ...payload } } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React, { ReactNode, useContext, MouseEvent } from "react"; | ||
import { RouterContext } from "./Router"; | ||
|
||
interface LinkProps { | ||
to: string; | ||
children: ReactNode; | ||
} | ||
|
||
const Link: React.FC<LinkProps> = ({ to, children }) => { | ||
const { changePath } = useContext(RouterContext); | ||
|
||
const handleClick = (event: MouseEvent<HTMLAnchorElement>) => { | ||
event.preventDefault(); | ||
changePath(to); | ||
}; | ||
|
||
return ( | ||
<a href={to} onClick={handleClick}> | ||
{children} | ||
</a> | ||
); | ||
}; | ||
|
||
export default Link; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React, { ReactElement } from "react"; | ||
|
||
interface RouteProps { | ||
path: string; | ||
element: ReactElement; | ||
} | ||
|
||
const Route: React.FC<RouteProps> = () => { | ||
return null; // 실제로 렌더링하지 않음 | ||
}; | ||
|
||
export default Route; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { useState, createContext, ReactNode, FC, useEffect } from "react"; | ||
|
||
interface RouterProps { | ||
children: ReactNode; | ||
} | ||
|
||
interface RouterContextType { | ||
path: string; | ||
changePath: (path: string) => void; | ||
} | ||
|
||
const RouterContext = createContext<RouterContextType>({ | ||
path: "", | ||
changePath: () => undefined, | ||
}); | ||
RouterContext.displayName = "RouterContext"; | ||
|
||
const Router: FC<RouterProps> = ({ children }) => { | ||
const [path, setPath] = useState(window.location.pathname); | ||
|
||
useEffect(() => { | ||
const handleLocationChange = () => { | ||
setPath(window.location.pathname); | ||
}; | ||
|
||
window.addEventListener("popstate", handleLocationChange); | ||
|
||
return () => { | ||
window.removeEventListener("popstate", handleLocationChange); | ||
}; | ||
}, []); | ||
|
||
const changePath = (newPath: string) => { | ||
if (path !== newPath) { | ||
window.history.pushState({}, "", newPath); | ||
setPath(newPath); | ||
} | ||
}; | ||
|
||
const contextValue = { | ||
path: path, | ||
changePath: changePath, | ||
}; | ||
|
||
return ( | ||
<RouterContext.Provider value={contextValue}> | ||
{children} | ||
</RouterContext.Provider> | ||
); | ||
}; | ||
|
||
export { Router, RouterContext }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React, { | ||
useContext, | ||
ReactElement, | ||
ReactNode, | ||
isValidElement, | ||
} from "react"; | ||
import { RouterContext } from "./Router"; | ||
|
||
interface RoutesProps { | ||
children: ReactNode; | ||
} | ||
|
||
const Routes: React.FC<RoutesProps> = ({ children }) => { | ||
const { path } = useContext(RouterContext); | ||
|
||
let element: ReactElement | null = null; | ||
|
||
React.Children.forEach(children, (child) => { | ||
if (!isValidElement(child)) { | ||
return; | ||
} | ||
if (child.type === React.Fragment) { | ||
return; | ||
} | ||
if (!child.props.path || !child.props.element) { | ||
return; | ||
} | ||
if (child.props.path !== path) { | ||
return; | ||
} | ||
element = child.props.element; | ||
}); | ||
|
||
return element; | ||
}; | ||
|
||
export default Routes; |
File renamed without changes