I am trying to following this react router redux so I can redirect using the push('/') in my components or actions.
Tutorial: https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux
I am not sure what I missing but I am getting an error.
The error I am getting in chrome console is:
bundle.js:3090 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of
Root
. in Root printWarning @ bundle.js:3090bundle.js:2684 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
bundle.js:20893 The above error occurred in the component: in Provider (created by Root) in Root
index.js
import React from 'react';
import { render } from 'react-dom';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import { routerReducer, routerMiddleware, push } from 'react-router-redux'
import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory';
import reducers from './reducers';
import Root from './root';
// Create a history of your choosing (we're using a browser history in this case)
const history = createHistory();
let middleware = [thunk, routerMiddleware(history)]
const store = createStore(
combineReducers({
...reducers,
router: routerReducer
}),
applyMiddleware(...middleware)
);
render(
<Root store={store} history={history} />,
document.getElementById('app')
);
root.js
import React from 'react';
import PropTypes from 'prop-types';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
} from 'react-router-dom';
import { ConnectedRouter } from 'react-router-redux';
import { Provider } from 'react-redux';
import App from './components/app';
const Root = ({ store, history }) => (
<Provider store={store}>
<ConnectedRouter history={history}>
<div className="application-container">
<App>
<Switch>
</Switch>
</App>
</div>
</ConnectedRouter>
</Provider>
);
Root.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
};
export default Root;
/reducers/index.js
import { combineReducers } from 'redux';
import users from './users';
const reducers = combineReducers({
users,
});
export default reducers;
users.js
import Constants from '../constants';
const initialState = {
users: [],
fetching: false,
};
const users = (state = initialState, action) => {
switch (action.type) {
case Constants.LOADING_USERS:
return {...state, fetching: true};
default:
return state;
}
};
export default users;
my package.json deps:
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.2",
"babel-plugin-react-display-name": "^2.0.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-0": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.26.0",
"colors": "^1.1.2",
"compression": "^1.7.1",
"eslint": "^4.15.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-babel": "^4.1.2",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.5.1",
"eslint-watch": "^3.1.3",
"express": "^4.16.2",
"jest": "^22.0.6",
"node-sass": "^4.7.2",
"npm-run-all": "^4.1.2",
"redux-devtools": "^3.4.1",
"sass-loader": "^6.0.6",
"webpack": "^3.10.0",
"webpack-dev-middleware": "^2.0.4",
"webpack-dev-server": "^2.10.1",
"webpack-hot-middleware": "^2.21.0"
},
"dependencies": {
"axios": "^0.17.1",
"history": "^4.7.2",
"lodash": "^4.17.5",
"moment": "^2.20.1",
"react": "^16.2.0",
"react-dnd": "^2.5.4",
"react-dnd-html5-backend": "^2.5.4",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-router-redux": "^4.0.8",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0"
},
There are several ways to redirect a user to another route, including the history.push () method and the <Redirect /> component from react-router. In this guide, we will use a Redux action to redirect the user using the <Redirect /> component. We will dispatch an action to redirect a user to the home page after they submit a registration form.
With Redux, however, implementing undo history is a breeze. There are three reasons for this: There are no multiple models—just a state subtree that you want to keep track of. The state is already immutable, and mutations are already described as discrete actions, which is close to the undo stack mental model.
The first set of things to do are with the Redux store. 1. Create a history object Technically, there’s a DOM history object for manipulating the browser’s history session. Let’s programmatically create one ourselves. ... import { createBrowserHistory } from 'history' ...
A simple solution would be to check for a state change in componentDidUpdate. Once your state has updated as a result of a successful redux action, you can compare the new props to the old and redirect if needed.
This could be an issue with dependency mismatch. The repository also mentions something regarding this:
This (react-router-redux 5.x) is the version of react-router-redux for use with react-router 4.x. Users of react-router 2.x and 3.x want to use react-router-redux found at the legacy repository.
Here is a working codesandbox set with react-router-redux
5.x and react-router
4.x for the same tutorial.
Update: Seems like you're using react-router-redux
4.x which might be causing the errors. This sandbox uses v4.x and throws errors
If you are not doing a server side rendering then use BrowserRouter instead in your root.js (See above). This is inside package react-router-dom.
import { BrowserRouter } from 'react-router-dom'
I would use ConnectedRouter (from react-router-redux) in root.js file only when I am doing serverside rendering. In this case when Hydrate happens (in index.js) in will not throw errors and warnings.
OR Please try this. Correct your routing with a ConnectedSwitch as shown in below example:
const AppContainer = () => (
<ConnectedSwitch>
<Route exact path="/" component={() => (<h1>Home <Link to="/about">About</Link></h1>)} />
<Route path="/about" component={() => (<h1>About <Link to="/">Home</Link></h1>)} />
</ConnectedSwitch>
)
const App = connect(state => ({
location: state.location,
}))(AppContainer)
render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
document.getElementById('root'),
)
I am open for discussion. Regards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With