/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
v17.0.2
fixtures/blocks/src/Router.js
105 строк
2 KB
Dan Abramov
[Blocks Fixture] Drop the Blocks (#18837)
06 май 2020, 07:17
Не верифицирован
06 май 2020, 07:17
595d27b
Код
Авторство
О чём код?
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React, { useReducer, useEffect, unstable_useTransition as useTransition, useCallback, useMemo, Suspense, } from 'react'; import {createCache, CacheProvider} from 'react/unstable-cache'; import {RouterProvider} from './client/RouterContext'; // TODO: can't really import a server component on the client. import App from './server/App'; const initialUrl = window.location.pathname; const initialState = { // TODO: use this for invalidation. cache: createCache(), url: initialUrl, pendingUrl: initialUrl, root: <App route={initialUrl} />, }; function reducer(state, action) { switch (action.type) { case 'startNavigation': return { ...state, pendingUrl: action.url, }; case 'completeNavigation': // TODO: cancel previous fetch? return { ...state, url: action.url, pendingUrl: action.url, root: action.root, }; default: throw new Error(); } } function Router() { const [state, dispatch] = useReducer(reducer, initialState); const [startTransition, isPending] = useTransition({ timeoutMs: 1500, }); useEffect(() => { document.body.style.cursor = isPending ? 'wait' : ''; }, [isPending]); const navigate = useCallback( url => { startTransition(() => { // TODO: Here, There, and Everywhere. // TODO: Instant Transitions, somehow. dispatch({ type: 'completeNavigation', root: <App route={url} />, url, }); }); dispatch({ type: 'startNavigation', url, }); }, [startTransition] ); useEffect(() => { const listener = () => { navigate(window.location.pathname); }; window.addEventListener('popstate', listener); return () => window.removeEventListener('popstate', listener); }, [navigate]); const routeContext = useMemo( () => ({ pendingUrl: state.pendingUrl, url: state.url, navigate, }), [state.url, state.pendingUrl, navigate] ); return ( <Suspense fallback={<h2>Loading...</h2>}> <CacheProvider value={state.cache}> <RouterProvider value={routeContext}>{state.root}</RouterProvider> </CacheProvider> </Suspense> ); } export default Router;