How use redux state with routes react-router? - react-router

I created my routes
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="/redux" component={redux} />
</Router>
</Provider>
My problem is when I dispatch an action from redux component , the props changed in the /redux route but in the / always the initial state. Please who can help me ?

Try to use react-router-redux (https://github.com/reactjs/react-router-redux) to synchronise redux store with react-router.
import { browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';
import { createStore, combineReducers } from 'redux';
// Add router reducer to your store on the `routing` key
const store = createStore(
combineReducers({
...reducers,
routing: routerReducer
})
)
// Create enhanced history that syncs navigation events with the store
const history = syncHistoryWithStore(browserHistory, store);
...
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<Route path="/redux" component={redux} />
</Router>
</Provider>

Related

React Routes Did not response and cant route [duplicate]

Before importing react-router it was working fine. Now it build successfully but shows a blank page. Here is my code:
App.js
//import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Pending from './Pages/Home';
import Home from './Pages/Pending';
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={Home} />
<Route path="/Pending" element={Pending} />
</Routes>
</BrowserRouter>
);
}
Home.js
import React, { Component } from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
import NavBar from '../components/NavBar';
function Home(){
return(
<div>
<div>
<NavBar/>
</div>
<h1>HI</h1>
</div>
);
}
export default Home;
Issue
The Route component API changed in react-router-dom#6. All routed content is now rendered on a single element prop as a ReactNode, a.k.a. JSX, not a reference to a React component.
Solution
Render the routed components as JSX, i.e. <Home /> instead of Home.
import { BrowserRouter, Routes, Route } from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Pending from './Pages/Home';
import Home from './Pages/Pending';
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/Pending" element={<Pending />} />
</Routes>
</BrowserRouter>
);
}
You should specify which version of react-router-dom you are using. So I'm just gonna assume, you are using the latest v6.
In your App.js file, you have to make the following changes in order to work:
import { Routes, Route } from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Pending from './Pages/Home';
import Home from './Pages/Pending';
export default function App() {
return (
<Routes>
<Route index path="/" element={<Home />}/>
<Route path="pending" element={<Pending />} />
</Routes>
);
}
For more info, please visit the official documentation here!
import './App.css';
import { BrowserRouter as Router , Route, Routes } from "react-router-dom";
import Header from './Components/Header';
import Footer from './Components/Footer';
import Home from './Components/Home';
import About from './Components/About';
function App() {
return (
<>
<Router>
<Header/>
<Routes>
<Route path="/" element={ <Home/> } />
<Route path="/About" element={ <About/> } />
</Routes>
<Footer/>
</Router>
</>
);
}
export default App;

React Router is showing only one of the Switch components and does nothing when others are called

My routing component looks like this:
import { Link, Route, Switch } from 'react-router-dom';
import Nav from 'react-bootstrap/Nav'
import AllWorkouts from './Workout/AllWorkouts/AllWorkouts';
import WorkoutCreate from './Workout/WorkoutCreate/WorkoutCreate';
import WorkoutDetails from './Workout/WorkoutDetails/WorkoutDetails';
import WorkoutEdit from './Workout/WorkoutEdit/WorkoutEdit';
const Main = () => {
return (
<Switch>
<Route path="/workout/:id/edit" componnet={WorkoutEdit} />
<Route path="/workout/:id/details" componnet={WorkoutDetails} />
<Route path="/workout/create" componnet={WorkoutCreate} />
<Route path="/workout/all" component={AllWorkouts} />
</Switch>
);
}
export default Main;
I have included BrowserRouter in index.js and the only route that is matching is path="/workout/all". I cannot call any of the other routs with Link or directly in the URL.
When I call /workout/all I can see the component with all the other routes nothing happens.
Thank you!
Below is the other component and I do not see any misspelling error:
import { Link, Route, Switch } from 'react-router-dom';
import Button from 'react-bootstrap/Button'
const AllWorkouts = () => {
return (
<div>
<Link to="/workout/create">
<Button variant="outline-primary">Create new workout</Button>{' '}
</Link>
<h1>Hello from AllWorkouts</h1>
</div>
);
}
export default AllWorkouts;
You have misspelled component in the other routes
mport { Link, Route, Switch } from 'react-router-dom';
import Nav from 'react-bootstrap/Nav'
import AllWorkouts from './Workout/AllWorkouts/AllWorkouts';
import WorkoutCreate from './Workout/WorkoutCreate/WorkoutCreate';
import WorkoutDetails from './Workout/WorkoutDetails/WorkoutDetails';
import WorkoutEdit from './Workout/WorkoutEdit/WorkoutEdit';
const Main = () => {
return (
<Switch>
<Route path="/workout/:id/edit" component={WorkoutEdit} />
<Route path="/workout/:id/details" component={WorkoutDetails} />
<Route path="/workout/create" component={WorkoutCreate} />
<Route path="/workout/all" component={AllWorkouts} />
</Switch>
);
}
export default Main;

React Router Dom v5 nested routes don't work

Been trying to figure out why the nested routes don't work in my child component. What am I missing here? Below is the component that fails to display anything when trying both routes "/" and "/add-new-strategy".
Here is my component.
import React from 'react'
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom'
import { Nav } from '../../Nav'
import { Home } from '../Home'
import { Admin } from '../Admin'
import './index.scss'
export const App = () => {
return (
<Router>
<main className="main-container">
<Nav />
<Switch>
<Route path="/admin">
<Admin />
</Route>
<Route path="/" exact>
<Home />
</Route>
</Switch>
</main>
</Router>
)
}
And this is the child component that is not displaying anything even though I have the and done.
import React from 'react'
import {
Switch,
Route
} from 'react-router-dom'
import { AdminSideBar } from '../../AdminSideBar'
import { AddNewStrategy } from '../AddNewStrategy'
export const Admin = () => {
return (
<div className="container-fluid">
<div className="row">
<AdminSideBar />
<div className="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<Switch>
<Route path="/add-new-strategy">
<AddNewStrategy />
</Route>
<Route path="/" exact>
Dashboard should show up here...
</Route>
</Switch>
</div>
</div>
</div>
)
}
Any help would be appreciated.
Try:
import { BrowserRouter, Route, Switch } from 'react-router-dom'
<BrowserRouter>
<Switch>
<Route path="/add-new-strategy" component={AddNewStrategy} />
<Route path="/" exact component={Dashboard} />
</Switch>
</BrowserRouter>
I found out that using useRouteMatch to specify the full path worked.
import React from 'react'
import {
Switch,
Route,
useRouteMatch
} from 'react-router-dom'
import { AdminSideBar } from '../../AdminSideBar'
import { AddNewStrategy } from '../AddNewStrategy'
export const Admin = () => {
const { path } = useRouteMatch()
return (
<div className="container-fluid">
<div className="row">
<AdminSideBar />
<div className="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<Switch>
<Route path={`${path}/add-new-strategy`}>
<AddNewStrategy />
</Route>
<Route path={path} exact>
Dashboard should show up here...
</Route>
</Switch>
</div>
</div>
</div>
)
}
there are 2 more methods to route from a component to next,
<Route path="/add-new-strategy" component={AddNewStrategy} />
or
<Route path="/" exact render={()=>{<AddNewStrategy/>}} />
for nested routing define full url and give exact 'true'
<Route path="/firstcomponent/secondcomponent" exact component={AddNewStrategy} />
please try these

React router multiple <Switch>

I'm using "react-router-dom": "^4.3.1",, "#material-ui/core": "^3.9.2",
I got router.ts which has Route, Switch and MainPage component.
router.ts
<HashRouter>
<div id="App">
<Appbar />
<Switch>
<Route exact path="/" component={MainPage} />
<Route exact path="/signup" component={SignupPage} />
<Route exact path="/signup/success" component={SignupSuccessPage} />
<Route exact path="/room/:id" component={NovelPage} />
<Route component={NotfoundPage} />
</Switch>
</div>
</HashRouter>
And I got MainPage component which has Route and Switch
<AppBar position="static">
<Tabs
variant="fullWidth"
value={this.state.value}
indicatorColor="primary"
textColor="primary"
>
<Tab
label={"latest_novel"}
onChange={this.handleTabsChange(`/latest/novel`, 0)}
/>
<Tab
label={"create novel"}
onChange={this.handleTabsChange(`/create/room`, 1)}
/>
</Tabs>
<Switch>
<Route exact path={`${this.props.match.url}/latest/novel`} component={TodayNovelPage} />
<Route exact path={`${this.props.match.url}/create/room`} component={CreateRoomPage} />
</Switch>
</AppBar>
I expected
When I click Mainpage's Tab component then, page url is changed like "localhost:3000/latest/novel" and page is moved.
When page is moved then it shows under MainPage's Switch
But, when I tried it.
Page is moved but, Tabs is disappears and it seemed shows under the router.ts not Mainpage. Why is it?
Please let me know if you need more info.
Thanks.
You should have common parent route for both the tabs.
Please check below example which I have created.
https://codesandbox.io/s/zz2xnn9p7m
Index.js
import React from "react";
import ReactDOM from "react-dom";
import { Switch, Route, Redirect, BrowserRouter } from "react-router-dom";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import MainPage from "../src/mainPage";
import "./styles.css";
function App() {
return (
<div className="App">
<AppBar position="static">
<Toolbar>
<Typography variant="h6" color="inherit">
Relay Novel
</Typography>
</Toolbar>
</AppBar>
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Redirect to="/mainPage" />} />
<Route path="/mainPage" component={MainPage} />
</Switch>
</BrowserRouter>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
MainPage.js
import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import { Switch, Route, Redirect, Link } from "react-router-dom";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { value } = this.state;
return (
<Fragment>
<Tabs value={value} onChange={this.handleChange}>
<Tab label="Latest Novel" component={Link} to="/mainPage/tab1" />
<Tab label="Create Novel" component={Link} to="/mainPage/tab2" />
</Tabs>
<Switch>
<Route exact path="/mainPage" />
<Route path="/mainPage/tab2" render={() => <div>Latest Novel</div>} />
<Route path="/mainPage/tab1" render={() => <div>Create Novel</div>} />
</Switch>
</Fragment>
);
}
}
export default MainPage;

React router throws and error when getting async component

I'm using react, redux and react router amoung others to build and example app.
I'm trying to load asynchronously different parts of my application. I've divided my app in ducks and I'm following this example https://github.com/insin/react-examples/tree/master/code-splitting-redux-reducers
But I'm getting this error:
Uncaught Invariant Violation: The root route must render a single element
When trying to get async component with getComponent method of react router.
I'm using:
react-router 2.0.1
My routes:
export default function configureRoutes(reducerRegistry) {
return(
<Route>
<Route component={Landing}>
<Route path='/login' component={Login}/>
<Route path='/register' component={Register}/>
</Route>
<Route path="admin" getComponent={(location, cb) => {
require.ensure([], require => {
cb(null, require('./containers/admin'))
})
}}/>
<Route component={App}>
<Route path='/' component={Home} />
</Route>
</Route>
)}
My component
class Admin extends Component {
componentDidMount() {
this.props.load()
}
render() {
const { message, isFetching } = this.props
return (
<div>
<p>{message}</p>
<p>This module was loaded via chunk </p>
{loading && <p>Doing some fake loading ...</p>}
</div>
)
}
}
Admin.propTypes = {
message: PropTypes.string.isRequired,
isFetching: PropTypes.bool.isRequired,
load: PropTypes.string.isRequired
}
const mapStateToProps = state => state.admin
function mapDispatchToProps(dispatch) {
return bindActionCreators({ load }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(Admin)
Does anyone have the same error? any ideas? Anyone have something similar working?
Thanks community!
Update: Added index.js for clarity
import configureRoutes from './routes'
import configureStore from './store/configureStore'
import coreReducers from './modules/core'
import ReducerRegistry from './reducer-registry'
var reducerRegistry = new ReducerRegistry(coreReducers)
// Configure hot module replacement for core reducers
if (process.env.NODE_ENV !== 'production') {
if (module.hot) {
module.hot.accept('./modules/core', () => {
var nextCoreReducers = require('./modules/core')
reducerRegistry.register(nextCoreReducers)
})
}
}
const routes = configureRoutes(reducerRegistry)
const store = configureStore(reducerRegistry)
render(
<I18nextProvider i18n={i18n}>
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>
</I18nextProvider>,
document.getElementById('root')
)
I think your root <Route> is missing the component field.
You need to specify either component or getComponent for every parent route, as this will be the component that the current child route’s component gets passed to as this.props.children.
Rather than
export default function configureRoutes(reducerRegistry) {
return (
<Route>
you want something like
export default function configureRoutes(reducerRegistry) {
return (
<Route component={App}>
In this case, you probably won’t need another App route below.