如何使用带有Preact的React路由器
How to use React Router with Preact
我正在使用Preact作为我的View框架(由于Facebook IP问题,不能使用React)。我需要使用React路由器进行位置路由,因为它比同一团队构建的Preact路由器更灵活。
我设法让React Router接受Preact来代替React,然而,我无法让它匹配位置。我不确定是兼容性问题还是配置问题。我试过只使用一对路由(应用程序和帐户),但它仍然无法使用简化的设置。
问:有人看到我在这里做错了什么吗?
我得到的错误是: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;
};
(OP已经解决了他的问题,但这在谷歌排名很高,对新手没有太大帮助,所以我想我应该提供一些背景信息)
Preact和Preact compat
preact是React的最小版本,重量只有3Kb。它实现了React的API的一个子集,这里和那里有一些小的差异。它还附带了一个助手库preact-compat,它通过填充缺失的部分和修补API差异来提供与React的兼容性。
React路由器
react router是一个路由器库,旨在与react一起工作。但是您也可以使用preact-compat
使其与Preact一起工作。
设置预作用compat
npm i --save preact-compat
请确保在webpack/浏览配置中为react
和react-dom
设置了别名,或者编写一些代码手动设置这些别名。
webpack配置示例
{
// ...
resolve: {
alias: {
'react': 'preact-compat',
'react-dom': 'preact-compat'
}
}
// ...
}
然后您可以按原样使用React Components。他们不会知道自己被Preact i.s.o.React渲染了。看看这个说教式的compat例子。
兼容性问题
请记住,当您使用Preact Compat时,您是在冒险。杰森是一个非常聪明的人,但他的图书馆只有脸书提供的图书馆的一小部分,所以肯定会有一些不同。使用React鲜为人知的功能的组件可能无法正常工作。如果你遇到这样的问题,请将其报告给传教士compat问题跟踪器(以GitHub回购的形式进行最小限度的复制),以帮助他改进。
过去曾有一些这样的问题使React Router无法与Preact正常工作,但自那以后,这些问题已经得到了解决,现在您应该能够很好地将两者结合使用。
Preact+React路由器的Fiddle
看看这个JS Fiddle的工作示例。
更新后的答案是现在有一个预启动路由器包: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与React:兼容性的两个问题
上下文处理不正确:
https://github.com/developit/preact/issues/156
props.children
未正确处理:
https://github.com/developit/preact-compat/issues/47#issuecomment-220128365
这里是支持hash的precat路由器的扩展解决方案。适用于重新加载和直接访问。
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路由器
- 如何在react路由器的组件中使用参数
- React路由器服务器端渲染和ajax获取数据
- react路由器使用简单的javascript路由器配置来处理不匹配的路径
- React路由器错误-'无法调用方法'getRouteAtDepth'的未定义'
- 有条件地与react路由器链接
- 如何使用服务器上的react路由器处理所有可能的路由
- React.js-React路由器内容未更改
- 使用react路由器隐藏组件
- React 路由器 activeClassName 不会为子路由设置活动类
- react路由器(-redux)未匹配路由
- 从使用react路由器的网络应用程序解析物理URL
- React 路由器和任意查询参数:页面在加载时无意中刷新
- 如何使用react路由器的正常锚链接
- 未捕获的类型错误:hook.apply不是在react路由器中使用onEnter时的函数
- 我可以让react路由器只覆盖一些url,并将其余的url正常传递给服务器吗
- Meteor's Accounts.onEmailVerificationLink与React和React路由器
- React路由器仅模式路由
- 当react路由器更改时,我们可以取消api响应吗
- React,Flux,React路由器调度错误-可能的批更新解决方案