Reputation: 157
I'm trying to run a book example that features a movies store. I've got the page to pull up and look right. The trouble is, when I click on a movie image nothing happens (the react-router is supposed to show an info box about the selected movie). My start URL is: http://localhost/~johndoe/react-dir/test-webpack/
When I click on a movie image nothing happens and the address bar changes to: http://localhost/movies/1
The Chrome dev tools, console says: browser.js:49 Warning: [react-router] Location "/movies/1" did not match any routes
My routes.js file is:
const React = require('react');
const {Router, Route, IndexRoute, browserHistory} = require('react-router');
const App = require('components/app/app.js');
const Movies = require('components/movies/movies.js');
const Movie = require('components/movie/movie.js');
module.exports = (
<Router history={browserHistory}>
<Route path={"/~johndoe/react-dir/test-webpack/"} component={App}>
<IndexRoute component={Movies}/>
<Route path={"movies"} component={Movies}>
<Route path={":id"} component={Movie}/>
</Route>
</Route>
</Router>
);
Can anyone suggest what might be going wrong? I'm not sure what to look for to fix this. Any help would be appreciated.
Upvotes: 0
Views: 143
Reputation: 19762
Alright took a bit to deconstruct what was going on, but here's a working version.
What's was going wrong:
array && array.length > 0
for arrays and/or Object.entries(obj).length === 0 && obj.constructor === Object
for objects. Without conditional rendering, when you clicked on the link, you were essentially breaking your app. What I changed:
isEmpty
. If the movies
or movie
value isn't present yet, it'll show a Loading...
or null
element.componentDidMount
and componentDidUpdate
lifecycles. Since React 16+, componentWillMount
and componentWillUpdate
have been deprecated and aren't recommended. import
and export
statements -- can't think of a reason to use module.exports
over import
and export
, especially if you're using babel to transpile your code. Now-a-days, you'll more than likely find the two bundled in a boilerplate. That said, you're more than welcome to make your life harder and not use babel
. :)redux-actions
as it obscures what's going on with redux
and its store
. So I separated everything out into actions
, reducers
, and types
. I find it easier to understand the flow (the circle of life):
connect
ed component, a user clicks an element (like a button), which triggers the action
.action
returns a type
and a payload
to the reducer
.reducer
matches against the type
and shallow merges the payload
into the reducer state
.connect
ed to redux accepts the new reducer state
as props
.Issues you'll have with your current setup:
movie.cover
in the codesandbox for examples) or import them directly into the file that requires them. movies/:id
, it'll break the application as movies
wouldn't be currently defined in your redux
state. As such, instead of using routing to showcase the details, I'd recommend using React's local state
to pop out and hide the detail view based upon which movie was clicked.Recommended:
react
and react-dom
from 15.2 to 16.x. and upgrading from react-router 2.6 to react-router-dom
or at the very least to react-router
v3+.Working example: https://codesandbox.io/s/nk715xpqv4 (the codesandbox CRA template doesn't support CSS modules, so I had to import the styles and use the className
as a string, but that doesn't mean you need to for your project).
Upvotes: 1