transform "Route children" and "cloneElement" to RouterV4 - javascript

I want to write a Router in React Project. But Route children and cloneElement work not anymore by Version 4. I haven't found demo or tutor to teach how to pass value in router in Router Version 4.
Have someone idea to solve that?
My project in Github: https://github.com/LeMueller/musicplayer-by-react/tree/dev
Thanks a lot.
import React, {Component} from 'react';
import Header from './commen/header.js';
import Player from './page/player.js';
import {MUSIC_LIST} from '../config/musiclist';
import MusicListUI from './page/musiclistui.js';
import {HashRouter, Switch, Route, Link} from 'react-router-dom';
class MusicApp extends Component{
constructor(props){
super(props);
this.state={
musiclist: MUSIC_LIST,
currentMusicItem: MUSIC_LIST[0]
}
}
componentDidMount(){
$('#player').jPlayer({
ready:function(){
$(this).jPlayer('setMedia',{
mp3:'http://oj4t8z2d5.bkt.clouddn.com/%E9%AD%94%E9%AC%BC%E4%B8%AD%E7%9A%84%E5%A4%A9%E4%BD%BF.mp3'
}).jPlayer('play');
},
supplied:'mp3',
wmode: 'window'
});
}
componentWillUnMount(){
}
render(){
return(
<div>
{React.cloneElement(this.props.children, this.state)}
</div>
)
}
}
export default class Root extends Component{
render(){
return(
<HashRouter>
<div>
<Header/>
<Route exact path="/" component={MusicApp}>
<Route exact path="/" component={Player }></Route>
<Route path="/list" component={MusicListUI}></Route>
</Route>
</div>
</HashRouter>
)
}
}

If you are looking to pass props to a component via a component, then you can use render, for example:
<Route exact path="/" render={(props) => <Player example={ props.example } /> }></Route>

Related

react router path parameter not working in class component

Well, I defined the react router as follows:
<BrowserRouter>
<Routes>
<Route path="/" exact element={<Home/>} />
<Route path="details/:id" element={<ViewNote/>}/>
</Routes>
</BrowserRouter>
and I called it like this in the class component:
import React, { Component } from 'react'
export default class ViewNote extends Component {
componentDidMount(){
console.log(this.props.match.params.id);
}
render() {
return (
<div>
<h2>{this.props.match.params.id}</h2>
</div>
)
}
}
But it shows match undefined in the console!!!
how to solve it??
thanks.

React router changes url but not re-render

React Router change the URL but the component is not rendered I have already looked for answer but none of those example is worked Current React Router & React Router DOM version is 6.
My MainComponent:
import React, { Component } from 'react';
import Header from './HeaderComponent';
import Footer from './FooterComponent';
import { Routes, Route, Redirect } from 'react-router-dom';
import Stafflist from './StaffComponent';
import {STAFFS} from '../shared/staffs';
import StaffDetail from './StaffDetailComponent';
class Main extends Component{
constructor(props){
super(props);
this.state ={
staffs : STAFFS
};
}
render(){
const StaffWithId = ({match}) =>{
return(
<StaffDetail staff={this.state.staffs.filter((staff) => staff.id === parseInt(match.params.staffId,10))}/>
)
}
return(
<div>
<Header/>
<Routes>
<Route exact path='/staff' element={<Stafflist staffs={this.state.staffs} />}/>
<Route path='/staff/:staffId' element={StaffWithId}/>
</Routes>
<Footer/>
</div>
);
}
}
export default Main;
Your problem seems to be this line:
<Route path='/staff/:staffId' element={StaffWithId}/>
StaffWithId is a functional component and shoul be called with brackets < />.
like this:
<Route path='/staff/:staffId' element={<StaffWithId/>}/>

Is function component that uses React-hook can be render inside from a class component

I use react-hook in my all component. Now when I want to render It's inside React_Router BrowserRouter component It's given me an error.
Error Massage: Invalid hook call. Hooks can only be called inside of the body of a function component
If I understand well your problem, I think you could do nested routes with hoo like it.
Here would be your main router for example:
import React from 'react';
import {Switch, Route, withRouter, Link} from "react-router-dom";
import MyComponent from "./MyComponent";
class Main extends React.Component
{
render() {
return (
<div className='main'>
<Switch>
<Route exact path='/test' component={MyComponent} />
</Switch>
</div>
);
}
}
export default withRouter(Main);
And Here would be your routed component with nested route.
import React from 'react';
import {Switch, Route, withRouter} from "react-router-dom";
class MyComponent extends React.Component
{
render()
{
const {path} = this.props.match;
return (
<div className='test'>
<Switch>
<Route path={`${path}/catalog`}>
<div>Route catalog</div>
</Route>
<Route exact path={path}>
<div>Route dashboard</div>
</Route>
</Switch>
</div>
);
}
}
export default withRouter(MyComponent);
I had the same error in the past days. In my case the problem was that i use render prop of Route component instead of component prop
<Route render={FunCompWithHooks} /> {/* wrong */}
<Route component={FunCompWithHooks} /> {/* correct */}

React Router Duplicate routes on Back Button

I have a react app. It is working fine. It uses redux,react-router 3. The routes work fine, but when I press the back button, they route gets duplicated. For example from localhost:3000/admin/main which I am currently, when I go back, it goes to localhost:3000/admin/admin/main, which return not found.
Here is my routes code:
export default (
<Route path="/" component={App}>
<Route path="home" component={requireNoAuthentication(HomeContainer)} />
<Route path="login" component={requireNoAuthentication(LoginView)} />
<Route exact path="admin/user" component={requireAuthentication(UserView)} />
<Route exact path="admin/main" component={requireAuthentication(UsersListView)} />
<Route path="secure" component={requireAuthentication(CustomerView)} />
<Route exact path="*" component={DetermineAuth(NotFound)} />
</Route>
);
I also get a console error: Adjacent JSX elements must be wrapped in an enclosing tag. If anyone can help it would be great thanks!!
Your HOC wrappers (requireNoAuthentication and requireAuthentication) and using exact (I think this might a react-router v4 only feature?) might be messing with your route history. Try restructuring your routes so that all of them fall under App -- some of the routes fall under RequireAuth, while the rest are public.
As a side note: you can avoid using React.cloneElement with passed down class methods and state by using Redux instead.
routes/index.js
import React from "react";
import { browserHistory, IndexRoute, Router, Route } from "react-router";
import App from "../components/App";
import Home from "../components/Home";
import Info from "../components/Info";
import ShowPlayerRoster from "../components/ShowPlayerRoster";
import ShowPlayerStats from "../components/ShowPlayerStats";
import Schedule from "../components/Schedule";
import Sponsors from "../components/Sponsors";
import RequireAuth from "../components/RequireAuth";
export default () => (
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route component={RequireAuth}>
<IndexRoute component={Home} />
<Route path="roster" component={ShowPlayerRoster} />
<Route path="roster/:id" component={ShowPlayerStats} />
<Route path="schedule" component={Schedule} />
</Route>
<Route path="info" component={Info} />
<Route path="sponsors" component={Sponsors} />
</Route>
</Router>
);
index.js
import React from "react";
import { render } from "react-dom";
import App from "../routes";
import "uikit/dist/css/uikit.min.css";
render(<App />, document.getElementById("root"));
components/App.js
import React, { Component, Fragment } from "react";
import { browserHistory } from "react-router";
import Header from "./Header";
export default class App extends Component {
state = {
isAuthenticated: false
};
isAuthed = () => this.setState({ isAuthenticated: true });
unAuth = () =>
this.setState({ isAuthenticated: false }, () => browserHistory.push("/"));
render = () => (
<Fragment>
<Header
isAuthenticated={this.state.isAuthenticated}
unAuth={this.unAuth}
/>
{React.cloneElement(this.props.children, {
isAuthenticated: this.state.isAuthenticated,
isAuthed: this.isAuthed
})}
</Fragment>
);
}
components/RequireAuth.js
import React, { Fragment } from "react";
import Login from "./Login";
export default ({ children, isAuthenticated, isAuthed }) =>
!isAuthenticated ? (
<Login isAuthed={isAuthed} />
) : (
<Fragment>{children}</Fragment>
);

Not able to render react component in react router

I have a react application.
i have problem in routing of component
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from './app';
ReactDOM.render(
<App/>,
document.getElementById("root")
);
app.jsx
Here i am routing 2 component. Login and Main component. In Main component there are many router which will use for dashboard.
My Problem : In <Switch> the 1st <Route> can render but it's not rendering from 2nd router if i hardcode in url
http://localhost:3000/#/login == rendering
http://localhost:3000/#/main = Not rendering
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom';
import Login from './login';
import Main from './main';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
class App extends Component {
constructor(props) {
super(props);
window.token = '';
}
render() {
return <div>
<Router>
<Switch>
<Route to="/login" component={Login} exact />
<Route to="/main" component={Main} exact/>
</Switch>
</Router>
</div>;
}
}
export default App;
main.jsx
import React, {Component} from 'react';
import ReactDOM from "react-dom";
import { HashRouter, Route, Switch } from "react-router-dom";
import indexRoutes from "routes/index.jsx";
import "bootstrap/dist/css/bootstrap.min.css";
import "./assets/css/animate.min.css";
import "./assets/sass/light-bootstrap-dashboard.css?v=1.2.0";
import "./assets/css/demo.css";
import "./assets/css/pe-icon-7-stroke.css";
import Login from './login';
class Main extends Component {
constructor(props) {
super(props);
}
render() {
return <HashRouter>
<Switch>
{indexRoutes.map((prop, key) => {
return <Route to={prop.path} component={prop.component} key={key} />;
})}
</Switch>
</HashRouter>;
}
}
export default Main;
Use
<Route path="/login" component={Login} exact />
Instead of to use path
<Route path="/login" component={Login} />
<Route path="/main" component={Main} exact/>
Use Path insted of To
Don't use exact attribute in main Route as shown below.
class App extends Component {
render() {
return <div>
<Router>
<Switch>
...
<Route to="/main" component={Main} />
</Switch>
</Router>
</div>;
}
}
There are two problems with your code
First in your app.jsx file:
<Switch>
<Route
to="/login" // <== should be path="/login"
component={Login}
exact
/>
<Route
to="/main" // <== should be path="/main"
component={Main}
exact // <== remove exact prop for the nested routes to work
/>
</Switch>
Here to prop actually belongs to the <Link/> component provided by react-router not the <Route /> component, It should be path prop.
If you want to render child routes within <Route /> component then we never use exact prop on the Parent <Route /> component.
Second in your main.jsx file:
indexRoutes.map((prop, key) => {
return (
<Route
to={prop.path} // <== should be path={prop.path}
component={prop.component}
key={key} />;
);
})
Again change to prop to path prop.

Categories