Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With react-router, redux will not work. #136

Closed
ustccjw opened this issue Jun 18, 2015 · 26 comments
Closed

With react-router, redux will not work. #136

ustccjw opened this issue Jun 18, 2015 · 26 comments

Comments

@ustccjw
Copy link

ustccjw commented Jun 18, 2015

I'm a flummox's user, as @acdlite suggest, i try to use redux.

I use react-router v1.0-beta2, I found when I use {this.props.children} to use 'component of redux', @connect, then will report error: Failed Context Types: Required context 'redux' was not specified in 'Connector'. Check the render method of 'Connector(DashboardApp)'

It seems react-router disabled the 'redux' context, so what should I do ?

@ooflorent
Copy link
Contributor

Can you attach a gist?

@ustccjw
Copy link
Author

ustccjw commented Jun 18, 2015

@provide(redux)
export default class App extends React.Component {
    constructor(props, context) {
        super(props)
    }

    static childContextTypes = {
        muiTheme: React.PropTypes.object
    }

    getChildContext() {
        return {
            muiTheme: ThemeManager.getCurrentTheme()
        }
    }

    render() {
        return (
            <div className="App">
                <Header />
                {this.props.children}
            </div>
        )
    }
}

@connect(state => ({
    counter: state.dashboard
}))
export default class DashboardApp extends React.Component {
    constructor(props, context) {
        super(props)
    }

    render() {
        const {counter, dispatch} = this.props;
        return (
            <Dashboard counter={counter}
                {...bindActionCreators(DashboardActions, dispatch)} />
        )
    }
}

@ooflorent
Copy link
Contributor

Including the router 😉

@ustccjw
Copy link
Author

ustccjw commented Jun 18, 2015

const rootRoute = {
    path: '/',
    childRoutes: [
        dashboard
    ],
    component: App
}

const dashboard = {
    path: 'dashboard',
    getComponents(cb) {
        require.ensure([], (require) => {
            cb(null, require('../containers/dashboard-app'))
        })
    }
}

@ooflorent
Copy link
Contributor

You must pass the context to super.

@ustccjw
Copy link
Author

ustccjw commented Jun 18, 2015

@ooflorent i update super(props, context), it always report the same error.

@gaearon
Copy link
Contributor

gaearon commented Jun 18, 2015

It won't work this way with Router 1.0, until React 0.14 comes out.

Top-level route handler (App) is not an owner of the lower level handlers (DashboardApp) so the context does not propagate. This will be fixed in React 0.14.

In the meantime, you need to wrap <Router> into <Provider> (I don't see where you render <Router> so can't give an exact example.)

@emmenko
Copy link
Contributor

emmenko commented Jun 18, 2015

@ustccjw this should help you to understand

emmenko/redux-react-router-async-example@c8e886f

The places to pay attention are:

  • how Provider wraps the routes
  • how to use @connect and pass actions (or extra props) to the child route
{React.cloneElement(this.props.children, { actions })}

@gaearon
Copy link
Contributor

gaearon commented Jun 18, 2015

Let's create a dedicated FAQ in the docs (separate from README) and put RR integration instructions there. Anybody want to do that?

@ustccjw
Copy link
Author

ustccjw commented Jun 18, 2015

@gaearon I can do it, i will try my best.

@ustccjw
Copy link
Author

ustccjw commented Jun 18, 2015

@emmenko thanks, i learn a lot.

@ustccjw ustccjw closed this as completed Jun 18, 2015
@emmenko
Copy link
Contributor

emmenko commented Jun 18, 2015

@gaearon I can do a PR later

@emmenko
Copy link
Contributor

emmenko commented Jun 18, 2015

@ustccjw glad to help :)

@ustccjw
Copy link
Author

ustccjw commented Jun 19, 2015

@emmenko in this way, can not hot-load store #117

@emmenko
Copy link
Contributor

emmenko commented Jun 19, 2015

@ustccjw to be fair, I haven't tried hot reloading in my example. What exactly is not working? Is it working without RR?

@ustccjw
Copy link
Author

ustccjw commented Jun 19, 2015

@emmenko #117 import your stores in App.js (root component), not index.js, so if import stores in index.js, the hot-loading will be failed.

As @gaearon said, this will wait react V0.14, then can import stores in App

import * as stores from './stores'
...
@provide(redux)
export default class App {
}

@gaearon
Copy link
Contributor

gaearon commented Jun 19, 2015

To have hot reloading properly working, you'll need to have a root component that returns <Router> wrapped in <Provider> from its render, and imports stores.

If you import stores in index.js, hot reloading them indeed won't work.

@ustccjw
Copy link
Author

ustccjw commented Jun 19, 2015

@gaearon you are right, it works! But react-router will throw error: Uncaught Error: Invariant Violation: <Router history> may not be changed.

@gaearon
Copy link
Contributor

gaearon commented Jun 19, 2015

@ustccjw

Thanks for reporting!
You should be able to do something like

class AppContainer extends Component {
  constructor(props) {
    this.history = new BrowserHistory();
    super(props);
  }

  render() {
    return (
      <Provider>{() =>
        <Router history={this.history}>
           ...
        </Router>
      }</Provider>
    );
  }

@mjackson @ryanflorence No plans to support swapping history object on the go?

@ustccjw
Copy link
Author

ustccjw commented Jun 19, 2015

@gaearon Thanks! You are great, I will to learn more from you!

ps. this can not use before super(), this should be

constructor(props) {
    super(props)
    this.history = new BrowserHistory()
}

@gaearon
Copy link
Contributor

gaearon commented Jun 19, 2015

Right.

@gaearon
Copy link
Contributor

gaearon commented Jun 19, 2015

@emmenko Can you please fix your RR project so hot reloading works taking this comment into account? #136 (comment)

@emmenko
Copy link
Contributor

emmenko commented Jun 19, 2015

@gaearon sure, I wanted to make it work first without HR, I'll do that as a second step

@justjacksonn
Copy link

Not sure if this is related... and/or I am stuck waiting for React final 0.14.. I am currently using 0.14 rc1. I would like to render a top header, bottom footer and then have my router paths render in between the header and footer areas.. the content area. However, my header is a top menu bar, with <Link...> elements in it.. and every time I use those, I get some sort of infinite loop happening and my entire browser halts.. I have to force quit it.

I assume this has something to do with that the header and footer components are rendered outside of the Provider? Is there some way to make the Link element (or even an element) work to change the content area of my page to the specified routed path/component? I would be fine with header/footer as well as content area inside the Provider tag.. but when I do that, the entire page gets redrawn including header/footer every time I click a link, and I am still stuck with the not working and crashing browser in the header component.

In other words, I am still not quite clear on the proper setup/integration of components with Redux and router. :) Appreciate any help on this.

@gaearon
Copy link
Contributor

gaearon commented Sep 25, 2015

Sorry, it is very hard what goes wrong in your particular case but I assure you it is not combining Redux and React Router itself that is the problem, but rather a mistake in using either of them (or something else entirely).

Please consult examples/real-world for React Router integration. If you still have this issue please provide a sample project reproducing it.

@adriennealyzee
Copy link

adriennealyzee commented Aug 26, 2016

@gaearon Thanks! I tried your code and now I get a different error:

Uncaught Invariant Violation: <Link>s rendered outside of a router context cannot navigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants