asmer 3 bulan lalu
induk
melakukan
be9fee163b
3 mengubah file dengan 32 tambahan dan 6 penghapusan
  1. 5 1
      src/App.tsx
  2. 1 1
      src/lib/index.ts
  3. 26 4
      src/lib/router/index.tsx

+ 5 - 1
src/App.tsx

@@ -4,13 +4,17 @@ import viteLogo from '/vite.svg'
 import './App.css'
 import {createBrowserHistory} from 'history';
 import {Router} from 'react-router-dom'
-import {NamedRoute, NamedLink} from './lib';
+import {NamedRoute, NamedLink, HashRoute} from './lib';
 
 const history = createBrowserHistory()
 
 const SwapiPeople = ({data:{name, eye_color}}) =>
 <div>
     <h3 style={{color: eye_color}}>{name}</h3>
+    <HashRoute path="/foo"  component={() => <h1>FOO</h1>} />
+    <HashRoute path="/bar"  component={() => <h1>BAR</h1>} />
+    <a href="#/foo">go to foo</a>
+    <a href="#/bar">go to bar</a>
 </div>
 
 const SwapiPlanet = ({data:{name, diameter}}) =>

+ 1 - 1
src/lib/index.ts

@@ -4,4 +4,4 @@ export {createPub};
 
 export type { Pub } from  './pub'
 export { usePub } from  './pub'
-export {NamedRoute, NamedLink} from './router'
+export {NamedRoute, NamedLink, HashRoute} from './router'

+ 26 - 4
src/lib/router/index.tsx

@@ -1,6 +1,6 @@
 import {ComponentType} from 'react';
 import {useState, useEffect} from 'react';
-import {Route, Link, generatePath} from 'react-router-dom';
+import {Route, Link, generatePath, matchPath, useHistory, useLocation} from 'react-router-dom';
 
 const routes = {
 
@@ -16,6 +16,7 @@ export const NamedRoute = ({name, routeName, query, pendingQueryComponent:P, err
         const [queryResult, setQueryResult] = useState()
         const [queryError, setQueryError] = useState()
         useEffect(() => {
+            console.log(props)
             if (query && typeof query === 'function'){
                 const querySyncResult = query(props.match.params, props, name)
                 if (querySyncResult && typeof querySyncResult.then === 'function'){
@@ -29,7 +30,7 @@ export const NamedRoute = ({name, routeName, query, pendingQueryComponent:P, err
                 setQueryError()
                 setQueryResult()
             }
-        },[props])
+        },Object.values(props.match.params))
 
         if (!query || typeof query !== 'function')
             return <Render {...{[componentQueryResultProp]:query, ...props}} />
@@ -40,8 +41,6 @@ export const NamedRoute = ({name, routeName, query, pendingQueryComponent:P, err
         if (queryError)
             return E ? <E {...{[errorQueryComponentErrorProp]: queryError, ...props}} /> : null
 
-        console.log({[componentQueryResultProp]:queryResult, ...props})
-
         return <Render {...{[componentQueryResultProp]:queryResult, ...props}} />
     }
 
@@ -57,4 +56,27 @@ export const NamedLink = ({routeName, params, to,...props}) => {
     return <Link to={to} {...props} />
 }
 
+export const HashRoute = ({component, render, ...props}) => {
+    const history = useHistory()
+    const location = useLocation()
+    const [match, setMatch] = useState<null|object>(null)
+    const checkMatch = () => {
+        setMatch(matchPath(window.location.hash.slice(1), props))
+    }
+    useEffect(checkMatch,[props.path, props.exact, props.strict, props.sensitive])
+    useEffect(() => {
+        window.addEventListener('hashchange', checkMatch)
+        return () => {
+            window.removeEventListener('hashchange', checkMatch)
+        }
+    },[])
+    if (!match) return null
+
+    const Render:ComponentType = component || render 
+
+    return <Render match={match} history={history} location={location} />
+}
+
+//export const HashNamedRoute = ({name, routeName, query, pendingQueryComponent:P, errorQueryComponent:E, errorQueryComponentErrorProp="error", componentQueryResultProp='data', path, component, render, ...props}) => {
+