Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use React Router with Preact

I'm using Preact as my View framework (can NOT use React due to the Facebook IP problems). I needed to use React Router for the location routing because it has more flexibility than the Preact Router that the same team built.

I managed to get React Router to accept Preact in place of React, however, I can't get it to match locations. I'm not sure if it's a compatibility problem, or a configuration problem. I've tried using just one pair of routes ( App and Account ) and it still doesn't work with that simplified setup.

Q: Does anyone see if I'm doing something wrong here?

The error I get is: 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;
};
like image 782
TbWill4321 Avatar asked May 18 '16 17:05

TbWill4321


1 Answers

Updated answer is there is a preact-router package now: 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);
like image 57
7zark7 Avatar answered Oct 26 '22 04:10

7zark7