Как использовать React Router с Preact

Я использую Preact в качестве рамки просмотра (can не используйте React из-за проблем с IP-адресом Facebook). Мне нужно было использовать React Router для маршрутизации местоположения, потому что он имеет большую гибкость, чем маршрутизатор Preact, который построила та же команда.

мне удалось заставить маршрутизатор React принять Preact вместо React, однако я не могу заставить его соответствовать местоположениям. Я не уверен, что это проблема совместимости или проблема конфигурации. Я пробовал использовать только одна пара маршрутов (приложение и учетная запись), и она по-прежнему не работает с этой упрощенной настройкой.

Q: кто-нибудь увидеть, если я делаю что-то неправильно здесь?

ошибка, которую я получаю:Location "/account/12345/" did not match any routes

main.js

import { h, render } from 'preact';
import { Router, browserHistory } from 'react-router';
import { Provider } from 'react-redux';

import createStore from './createStore';
import createRoutes from './createRoutes';

process.env.DEBUG && console.log('Hello, developer!');

const history = browserHistory;
const store = createStore( history );
const routes = createRoutes( store );

render((
    <Provider store={ store } key="redux-provider">
        <Router history={ history } createElement={ h } routes={ routes } />
    </Provider>
), document.body );

createRoutes.js

import { h } from 'preact';
import { IndexRoute, Route } from 'react-router';

// App Component
import App from './components/app';

// Sub Components
import Account from './components/account';
import Conversation from './components/conversation';
import Dashboard from './components/dashboard';

// Error Components
import BadAccount from './components/bad-account';
import NotFound from './components/not-found';

// Routes
export default ()=> (
    <Route path="/" component={App}>
        {/* Get URL parameter */}
        <Route path="account/:accountID" component={Account}>
            {/* Index Route */}
            <IndexRoute component={Dashboard} />
            {/* Sub Routes ( Alphabetical Please ) */}
            <Route path="chat" component={Conversation} />
            {/* Catch-All Route */}
            <Route path="*" component={NotFound} />
        </Route>
        {/* Handle Invalid URIs */}
        <Route path="*" component={BadAccount} />
    </Route>
);

createStore.js

import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux';

import messages from './resources/messages/reducer';
import conversation from './resources/conversation/reducer';
import layout from './resources/layout/reducer';
import profile from './resources/profile/reducer';
import contract from './resources/contract/reducer';

/*const { devToolsExtension } = window;*/

export default history => {

    // Sync dispatched route actions to the history
    const reduxRouterMiddleware = routerMiddleware( history );

    // Create single reducer from all modules
    const rootReducer = combineReducers({
        messages,
        conversation,
        layout,
        profile,
        contract
    });

    // List redux middleware to inject
    const middleware = [
        thunk,
        reduxRouterMiddleware
    ];

    // Compose the createStore function
    const createComposedStore = compose(
        applyMiddleware( ...middleware )/*, // Figure this out...
        ( process.env.DEBUG && devToolsExtension ) ? devToolsExtension() : f => f*/
    )( createStore );

    // Create the store
    const store = createComposedStore( rootReducer );

    // Hook up Redux Routing middleware
    // reduxRouterMiddleware.listenForReplays(store);

    // Return store
    return store;
};

4 ответов


(OP уже решил свою проблему, но это занимает высокое место в Google и не очень полезно для новичков, поэтому я подумал, что предоставлю некоторую справочную информацию)

сайт Preact и сайт Preact-совместимость

сайт Preact является минимальной версией React, которая весит всего 3 КБ. Он реализует подмножество API React, с некоторыми небольшими различиями здесь и там. Он также поставляется с вспомогательной библиотекой,preact-compat, который обеспечивает совместимость с Реагируйте, заполняя недостающие части и исправляя различия API.

React-Маршрутизатор

react-router - это библиотека маршрутизаторов, предназначенная для работы с React. Но вы можете заставить его работать и с Preact, используя preact-compat.

настройка preact-compat

npm i --save preact-compat

убедитесь, что вы настроили псевдонимы для react и react-dom в конфигурации webpack / browserify или напишите код для настройки этих псевдонимов вручную.

пример конфигурации webpack

{
    // ...
    resolve: {
        alias: {
            'react': 'preact-compat',
            'react-dom': 'preact-compat'
        }
    }
    // ...
}

затем вы можете использовать компоненты React как есть. Они не знают, что они оказывают на сайт Preact я.С. о'. Реагировать. Взгляните на это preact-compat-пример.

проблем с совместимостью

имейте в виду, что при использовании Preact Compat вы рискуете. Джейсон-очень умный парень, но его библиотека-это только часть размера той, которую предоставляет Facebook, поэтому там обязательно некоторые отличия. Компоненты, использующие менее известные функции React, могут работать неправильно. Если вы столкнулись с такими проблемами, сообщите о них в preact-compat проблема tracker (С минимальным воспроизведением в виде РЕПО GitHub), чтобы помочь ему улучшить его.

в прошлом было несколько таких проблем, которые помешали React-Router правильно работать с Preact, но они были исправлены, и теперь вы сможете использовать их вместе.

Скрипка Preact + React-маршрутизатор

посмотреть это JS Скрипка рабочий пример.


обновленный ответ теперь есть пакет preact-router:https://www.npmjs.com/package/preact-router

import Router from 'preact-router';
import { h } from 'preact';

const Main = () => (
  <Router>
    <Home path="/" />
    <About path="/about" />
    <Search path="/search/:query" />
  </Router>
);

render(<Main />, document.body);

вот расширенное решение для preact-router с поддержкой хэша. Работает с перезагрузкой и прямым доступом.

https://www.webpackbin.com/bins/-KvgdLnM5ZoFXJ7d3hWi

import {Router, Link} from 'preact-router';
import {h, render} from 'preact';
import {createHashHistory} from 'history';

[cut]...[/cut]

const App = () => (
    <div>   
      <Header />
      <Router history={createHashHistory()}>            
        <Page1 default path="/" />
        <Page2 path="/page2" />
      </Router>
    </div>
);    
render(<App />, document.body);

найдена проблема, была пара проблем с совместимостью Preact с React:

контексты не правильно:

https://github.com/developit/preact/issues/156

props.children не правильно:

https://github.com/developit/preact-compat/issues/47#issuecomment-220128365