Repository navigation
Conversation
| store.dispatch({ | ||
| type: LOCATION_CHANGE, | ||
| payload: { action, location } | ||
| }) |
There was a problem hiding this comment.
Won't this cause infinite re-renders? It's firing even if the location is the same and that will cause another render.
There was a problem hiding this comment.
Likely. I haven't given it a full rundown of tests. I'm thinking of potentially implementing an interim component that can use cWRP to do the location change.
| const { history:History, basename, keyLength, ...props } = this.props | ||
|
|
||
| return ( | ||
| <History location={location} basename={basename} keyLength={keyLength}> |
| {({ history, action, location }) => { | ||
| const store = this.context.store || this.props.store | ||
|
|
||
| store.dispatch({ |
There was a problem hiding this comment.
This causes a warning to be logged in the console
Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`
There was a problem hiding this comment.
I will likely move this to an interim component and use cWRP, which should address the issue.
There was a problem hiding this comment.
This could use some cleanup, but I tested it and it works without producing any warnings
class ConnectedRouter extends Component {
static propTypes = {
store: PropTypes.object,
history: PropTypes.func,
basename: PropTypes.string,
keyLength: PropTypes.number
}
static contextTypes = {
store: PropTypes.object
}
static defaultProps = {
history: BrowserHistory
}
render () {
const { history: History, basename, keyLength, ...props } = this.props
const store = this.context.store || this.props.store
return (
<History location={props.location} basename={basename} keyLength={keyLength}>
{({history, action, location}) => (
<BaseRouter {...{history, action, location, basename, ...props, store}} />) }
</History>
)
}
}
class BaseRouter extends Component {
componentDidMount () {
this.updateLocation(this.props.location, this.props.action)
}
componentWillReceiveProps (nextProps) {
this.updateLocation(nextProps.location, nextProps.action)
}
updateLocation = (location, action) => {
this.props.store.dispatch({
type: LOCATION_CHANGE,
payload: { location, action }
})
}
render () {
const { history, action, location, basename } = this.props
return (
<StaticRouter
action={action}
location={location}
basename={basename}
onPush={history.push}
onReplace={history.replace}
blockTransitions={history.block}
{...this.props}
/>)
}
}|
|
||
| return ( | ||
| <History location={props.location} basename={basename} keyLength={keyLength}> | ||
| <History basename={basename} keyLength={keyLength}> |
There was a problem hiding this comment.
Yes, it's not used on *History in react-history.
| store: PropTypes.object, | ||
| history: PropTypes.object, | ||
| action: PropTypes.string, | ||
| location: PropTypes.string, |
|
Looks, good. I'm running this without any issues. |
|
FYI, Ryan posted his |
|
@tyrsius How did you install this version into your project? I have installed this branch via npm git, as well as locally with npm link and I continue to see Anything you could share would be much appreciated! |
|
@kevinold I didn't. Without the redux actions I had no way to update the history object. I copied the |
|
If you check it out as a git submodule, you can just link to the file on the filesystem directly for now. You should only have to do that in one or two places. So something like |
|
@tyrsius Any chance you could share the changes you made to capture the history object? I've restored to your approach in copying the ControlledRouter and reducer into my project. I am seeing the LOCATION_CHANGE dispatched, but the history object is not updated. Any help is appreciated! |
|
Its _extremely_ hacky, but it was easy because I was already capturing and exposing the history object as a singleton in a local module, so instead of just exporting the object constructed from (reminder, this is a hacky stopgap until the actions are part of this module) -the history module import { createHistory } from 'history'
let _history = createHistory()
export default {
bind: (history) => {
_history = history
},
push: (...args) => _history.push(...args),
listen: (...args) => _history.listen(...args),
replace: (...args) => _history.replace(...args)
}my import React, { Component, PropTypes } from 'react'
import BrowserHistory from 'react-history/BrowserHistory'
import StaticRouter from 'react-router/StaticRouter'
import { LOCATION_CHANGE } from './reducer'
import history from 'PATH_TO_YOUR_MODULE/history.js'
class DispatchingRouter extends Component {
static propTypes = {
store: PropTypes.object,
history: PropTypes.oneOfType([ PropTypes.object, PropTypes.string ]),
action: PropTypes.string,
location: PropTypes.object,
basename: PropTypes.string
}
constructor (props) {
super(props)
history.bind(props.history)
this.handleLocationChange(this.props)
}
componentWillReceiveProps (nextProps) {
this.handleLocationChange(nextProps)
}
handleLocationChange = ({ store, action, location }) => {
store.dispatch({
type: LOCATION_CHANGE,
payload: { action, location }
})
}
render () {
const { history, action, location, basename, ...props } = this.props
return (
<StaticRouter
action={action}
location={location}
basename={basename}
onPush={history.push}
onReplace={history.replace}
blockTransitions={history.block}
{...props}
/>)
}
}
const fixHistory = (history) => {
history.location.search = history.location.search || ''
history.location.hash = history.location.hash || ''
return history
}
class ConnectedRouter extends Component {
static propTypes = {
store: PropTypes.object,
history: PropTypes.func,
basename: PropTypes.string,
keyLength: PropTypes.number
}
static contextTypes = {
store: PropTypes.object
}
static defaultProps = {
history: BrowserHistory
}
render () {
const { history: History, basename, keyLength, ...props } = this.props
return (
<History basename={basename} keyLength={keyLength}>
{({ history, action, location }) => {
return (
<DispatchingRouter
store={this.context.store || this.props.store}
history={fixHistory(history)}
action={action}
location={location}
basename={basename}
{...props}
/>)
}}
</History>
)
}
}
export default ConnectedRouter |
|
@tyrsius Thanks. I have your code working, but I'm still not seeing the change when calling history.pushState() manually, since I cannot get the history object to come down to my Wrapper component. Here's my code in index.js that calls I do not receive onPush, onReplace, etc. that are defined on StaticRouter or history that is defined on DispatchingRouter. My question is, if I am suppose to call onPush() or history.push() directly, how am I to get it passed down to to my Matched components? |
|
@kevinold ... I told you it was hacky. This is what I am doing, it works. I don't recommend it. Root.js import Router from 'devportal/root/routes.js'
import App from 'devportal/root/App.js'
export default class Root extends Component {
render () {
return (
<Provider store={this.props.store}>
<Router component={App} />
</Provider>
)
}
}Routes.js const Routes = ({component}) => {
var Component = component
return (
<ConnectedRouter>
<Match pattern='/' render={(props) => (
<Component {...props}>
<Match pattern='/' exactly component={SearchPage} />
// A bunch more matches
</Component>
)} />
</ConnectedRouter>
)
}
export default RoutesApp.js @connect(null, { /* actions */ })
export default class App extends Component {
render () {
return (
<div className='app-container'>
<NavBar />
<div className='app-body'>
{this.props.children}
</div>
<Footer />
</div>
)
}
}With all of this, calling |
|
Thanks @tyrsius, I think I see what you're doing here. I'll keep hacking around with it. I appreciate your help! |
|
Unfortunately, I am not able to get onPush, onReplace, etc. as props to my Wrapper component :( |
|
I experimented with an alternative approach to this: https://github.com/gmaclennan/react-router-sync It's pretty simple, and I may well be missing some of the complexity of react-router that I do not understand. See: https://github.com/gmaclennan/react-router-sync/blob/master/index.js It's just a regular React component that keeps a global state in sync by either calling I'd be interested to hear why this might not be a good approach. Not published on npm or anything, it's just proof of concept, but you can clone the repo and run the manual test and the redux example. |
|
This branch seems to be working well for me too. |
|
Based on several ideas here, I've made It works quite well in my use-case but, as a PoC, I may overlook several cases and need to check more. However, the time travel feature is still broken (but redux devtools works if we don't rewind). |
|
I believe this is broken by ReactTraining/react-history@258dec2#diff-4ee6183afe47173284dec5a54c9bdc90L57 it no longer passes different props to the Specifically, this function-as-children callback: Will no longer receive an object containing keys for history, action and location ... it will only receive a single "history" |
|
Just wanted to chime in with my support for this effort. I just started using React a month ago, and chose to learn and use React Router v4 since it was already out, rather than investing in a version who's EOL is visible. Now I'm studying Redux in preparation for adopting that as well, and it'd be nice to use the react-router-redux bindings, but I won't be able to until Router v4 is supported. |
|
@timdorr, do you think that there is real hope that you will be able to finish this during the holiday season? (Not demanding anything, just asking :) ) |
|
@lourd, @supasate, @gmaclennan, do you think it makes sense to use your versions in a real (commercial) project? Are you doing the same? How long do you plan on maintaining them? Thanks. |
|
@csillag I'm using and maintaining connected-react-router for our new customer project. The project is still in development phase, so, it's not on production yet but it has been working very well so far since I launched it. I plan to maintain it for a long run. I'm also happy to give it to |
|
@supasate works like a charm! Many thanks |
|
@supasate: Great to hear that! So that project is definitely one of my top candidates now. On the other hand, earlier @lourd wrote:
@lourd, is that still the case? |
|
Don't use my version! It was just an experiment and I'm not currently using
it. For now I am not storing URL state in Redux until there is more
feedback on the best solution.
Gregor MacLennan | Digital Democracy <http://digital-democracy.org/> |
US: 415.234.3373 | Peru: (01) 708 8702 | gmaclennan@digital-democracy.org |
@digidem <https://twitter.com/digidem>
On Tue, Dec 20, 2016 at 11:03 AM, Kristof Csillag <notifications@github.com>
wrote:
… @supasate <https://github.com/supasate>: Great to hear that! So that
project is definitely one of my top candidates now.
On the other hand, earlier @lourd <https://github.com/lourd> wrote:
I've been using the approach I mentioned at my job in our upcoming project
for a couple weeks and haven't had issues so far. I would recommend it over
the react-router-addons-controlled library. Source code here for reference.
@lourd <https://github.com/lourd>, is that still the case?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#460 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARumb0YUk1BKgtWfkB-HczUbxQWmUIcks5rJ-5JgaJpZM4KFhwq>
.
|
|
Hey @csillag. Yes, that's still the case. The project has been in QA for a couple weeks and went into production this week. We haven't had to change any of the react-router-redux example code that I posted earlier, it has been reliable and bug free. I can confidently recommend it. The main interface you'll interact with is the action creators, and those methods are not likely to change at all regardless of what version of React Router or RRR you're using since they correspond with the the methods that The configuration code between history, the store, and the router may change slightly from what my code does now depending on what @timdorr thinks, but it will not be more than 5-10 lines of code. |
|
Hey @csillag <https://github.com/csillag>. Yes, that's still the case. The
project has been in QA for a couple weeks and went into production this
week.
Great!
Is it published somewhere from where one can install it with npm?
(Outside the example code, I mean.)
|
|
No, it's not. My project has the code in a local folder right now. I didn't want to make a separate package as to kind of encourage me to clean it up and make an official PR here. |
|
I wouldn't work on any redux integration yet. The 4.0 API is still in flux and both Michael and Ryan have different potential implementations at the moment, neither of which match this branch. I will have to rewrite this once the API is settled on. |
|
Uhh... are you referring to the v4-alt branch on React Router? It looks like a distinctly different direction than the current v4 alpha. The change to a @mjackson, what's the motivation behind the alternative implementation? |
|
I just released connected-react-router v2.0.0-alpha.1. Currently, it already supports Redux DevTools Time Travel (thanks to @dictions). It contains breaking change from [Update] v2.0.0-alpha.2 is released. Now the browser URL is synced in Time Travel mode. |
|
Good news: I don't know what the reason is, but the v4-alt branch of the react-router is gone! |
|
Haha, not quite. It looks like most of the work from v4-alt is in the v4 branch now. API changes ahead. Main one looks like |
|
Ooh, so in the end, the |
|
Yeah, looks like. |
|
We folded everything in v4-alt into v4 this week, planning on shipping a v4 beta this next week with API that we've all agreed upon. @lourd No worries, you'll have a |
|
Any plans to create an alpha version of react-router-redux with v4 support? |
|
Closing since v4 has been majorly refactored. I'll restart something else for this soon once I've had enough time to check out the new code (I'm behind!). |


This revamps the library for React Router 4.0 integration.
This is one potential option for how we might integrate things. If not, we can definitely use this scaffolding as a base for something else.
Currently, this does one-way synchronization of the location from a
<*History>(from react-history) to a Redux store. I could have done a more generic<ControlledRouter>that exposes anonChangeprop, but this library has a specific purpose and I wanted to avoid excess boilerplate. The only complication is needing to add in an additional reducer. Not really a way to avoid that, but everyone should be used to that from the previous versions.Next up is being able to dispatch history actions into the store to issue navigation events.
Anyways, this is just a beginning and it's in a very mercurial state, so suggestions are definitely welcome.