Skip to content

Releases: acdlite/redux-router

Another version comes along! (1.0.0-beta6)

02 Jan 20:02
Compare
Choose a tag to compare

We are glad to be able to continue bringing this project forward. A big "thank you" goes out to @mjrussell, who did most of work of this release and hopefully will continue to do so (no pressure).

Update react-router

We updated react-routers version to 1.0.3 and we are already working on upgrading to react-router v2. As this upgrade will take some more work and testing, we chose to stay at v1.0.3 for now.

Update history

We removed the peerDependency to history as it did not work properly with older npm versions, also npm had a nasty bug with releasing modules containing history. Internally we updated history to 1.17.0.

Also we removed any direct import or require on our side, so s user has complete control over which createHistory function is handed over. This applies mainly to the server-side rendering module, which had the only direct import. To prevent people from using too old versions of history, we included a sanity check which checks the ´history´ a user hands over to us for the necessary functions (see #221).
This breaks things on server-side rendering, as you now need to add a createHistory function to the reduxRouter.
Check out the test to clarify things:
https://github.com/acdlite/redux-router/blob/master/src/__tests__/ReduxRouter-test.js#L201

Server-Side Rendering Example

We included a very basic server-rendering example to help people get started. Thanks to @stevoland.

v1.0.0-beta5

04 Dec 15:48
Compare
Choose a tag to compare

So this release basically bundles three PRs:

  1. #185:
    When using history basename function it returns an object. Before this
    it would only accept a function that returns an object. This update
    gives users the ability to use other helpers provided by history.
    Also take a look at the added test , it explains pretty well what´s possible now.
  2. #183:
    This fixes the infinite redirect loop in IE8&9 and also addresses some issues with router actions firing twice on the first load. We now got a INIT_ROUTES action for the initial load.
  3. #178:
    This allows you to switch out the default RoutingContext e.g. for RelayRoutingContext.

Thanks again @apapirovski, @vslinko and @agirton-twitter for your contributions!

Also we added history as a dependency. Tried it as a peerDependency but this seems to cause problems with older npm versions.

Also we want to bring #172 to your attention (again). We badly need contributions for redux-router, feel free to send us PRs or take part in the discussions on the issue trackers, if many people put in a little bit of effort it´ll be just as good as one full time contributor.

getRoutes() is back

17 Sep 17:46
Compare
Choose a tag to compare

It turns out that the dynamic routes feature from the last release won't work for server-side rendering, because the routes need to be specified before calling match(). You must pass routes (or getRoutes() — see below) directly to the reduxReactRouter() store enhancer when doing server-side rendering. We throw an error if you don't.

This makes circular dependencies (routes depend on store, store depends on routes) more difficult on the server, so this release also brings back a modified version of getRoutes().

reduxReactRouter({
  getRoutes({ getState, dispatch }) {
    // Return routes configuration
  }
})

Note that you can always use a closure to work around a circular dependency:

let store;

function doSomethingOnEnter() {
  store.dispatch(whatever);
}

const routes = (
  <Route>
    <Router path="/" onEnter={doSomethingOnEnter} />
  </Route>
);

store = reduxReactRouter({ routes })(createStore)(reducer, initialState);

This is essentially what getRoutes() does for you.

Thank you to everybody who has been testing the betas so we can identify and fix issues like these! I am optimistic about a stable 1.0 release coming out soon (or whenever React Router releases their 1.0).

Dynamic Route Configuration or: How I Learned to Stop Worrying and Love Circular Dependencies

16 Sep 04:03
Compare
Choose a tag to compare

Two big additions with this release.

Routes as children/props

Instead of passing your route configuration to the store enhancer, you now also have the option of passing it to <ReduxRouter> as either the routes prop or as children. This brings us in line with the normal React Router API.

Example:

ReactDOM.render((
  <Provider store={store}>
    <ReduxRouter>
      <Route path="/" component={App}>
        <Route path="parent" component={Parent}>
          <Route path="child/:id" component={Child} />
        </Route>
      </Route>
    </ReduxRouter>
  </Provider>
), el);

or, equivalently:

const routes = (
  <Route path="/" component={App}>
    <Route path="parent" component={Parent}>
      <Route path="child/:id" component={Child} />
    </Route>
  </Route>
);

ReactDOM.render((
  <Provider store={store}>
    <ReduxRouter routes={routes} />
  </Provider>
), el);

This solves the circular dependency problem (#44), where if you needed a reference to the store from within a route transition hook, you had to use a closure. This was confusing and easy to mess up; the new API does this for you using React Router's built-in dynamic routes functionality.

As a bonus, the router will respond to new props, so hot reloading totally works.

Server-side rendering

To render an app on the server, import the reduxReactRouter store enhancer from redux-react-router/server instead of the main module. This is a slightly different version of the enhancer with server-specific functionality. Also import the match() action creator:

import { match, reduxReactRouter } from 'redux-react-router/server'; 

Then set up your store like normal. You can omit createHistory and history if you like:

const store = compose(
  applyMiddleware(m1, m2, m3),
  reduxReactRouter()
)(createStore)(reducer);

The match() action creator is very similar to the match() function provided by React Router, except because it's an action creator, we dispatch the result. It accepts a URL and a callback:

store.dispatch(match('/some/path', (error, redirectLocation, routerState) => {
  if (error) {
    // handle error
  }

  if (redirectLocation) {
    // handle redirect
  }

  if (!routerState) {
    // handle 404
  }

  // Otherwise, render to string
  res.send(
    renderToString(
      <Provider store={store}>
        <Route path="/" component={App}>
          <Route path="some" component={Parent}>
            <Route path="path" component={Child} />
          </Route>
        </Route>
      </Provider>
    )
  );
}));

Fix extra dispatch after external state change

13 Jul 20:09
Compare
Choose a tag to compare

Noticed after testing with Redux Devtools that an extra, unnecessary action was being dispatched after an external state change. This PR fixes it by comparing location state keys before calling locationDidChange().