12

我使用 Preact 作为我的视图框架(由于 Facebook IP 问题,不能使用 React) 。我需要使用 React Router 进行位置路由,因为它比同一个团队构建的 Preact Router 具有更大的灵活性。

我设法让 React Router 接受 Preact 代替 React,但是,我无法让它匹配位置。我不确定这是兼容性问题还是配置问题。我试过只使用一对路由( App 和 Account ),但它仍然不适用于简化的设置。

问:有没有人看到我在这里做错了什么?

我得到的错误是: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

4 回答 4

15

(OP已经解决了他的问题,但这在谷歌中排名很高,对新手帮助不大,所以我想我会提供一些背景信息)

Preact 和 preact-compat

preact是 React 的最小版本,仅重 3Kb。它实现了 React API 的一个子集,这里和那里有一些小的差异。它还带有一个辅助库preact-compat,它通过填充缺失的部分和修补 API 差异来提供与 React 的兼容性。

反应路由器

react-router是一个路由器库,旨在与 React 一起使用。但是你也可以让它与 Preact 一起工作,使用preact-compat.

设置 preact-compat

npm i --save preact-compat

确保在 webpack / browserify 配置中设置别名reactreact-dom或者编写一些代码来手动设置这些别名。

示例 webpack 配置

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

然后你可以按原样使用 React 组件。他们不会知道他们正在被 Preact iso React 渲染。看看这个preact-compat-example

兼容性问题

请记住,当您使用 Preact Compat 时,您是在冒险。Jason 是一个非常聪明的人,但他的库只有 Facebook 提供的库的一小部分,所以肯定会有一些差异。使用 React 鲜为人知的功能的组件可能无法正常工作。如果您遇到此类问题,请将它们报告给preact-compat 问题跟踪器(以 GitHub 存储库的形式进行最小复制)以帮助他改进它。

过去有一些这样的问题阻止了 React-Router 与 Preact 一起正常工作,但它们已经得到修复,你现在应该能够很好地一起使用这两者。

Preact + React-Router 的小提琴

看看这个 JS Fiddle以获得一个工作示例。

于 2016-09-12T08:43:04.540 回答
3

更新的答案是现在有一个 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);
于 2016-08-30T05:46:21.180 回答
-1

发现问题,是 Preact 与 React 兼容性的一对问题:

未正确处理的上下文:

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

props.children未正确处理:

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

于 2016-05-19T15:22:44.960 回答
-1

这是具有哈希支持的 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);
于 2017-10-05T13:12:47.253 回答