React Router rendering wrong component - reactjs

I am using a HashRouter to render different pages. The problem I am having is that when I visit
/service/app/sort, it renders <MainPage /> when I am expecting it to render <ChildPage />.
Here's similar to what my router looks like
<HashRouter>
<Switch>
<Route path="/service/app">
<MainPage />
</Route>
<Route path="/service/app/sort">
<ChildPage />
</Route>
</Switch>
</HashRouter>
Additional information that may help:
on my <MainPage />, I have a button to redirect onClick
const history = useHistory();
const handleSortClick = () => {
console.log('click me')
let path = "/service/app/sort";
history.push(path);
};
When I click it once, I get the 'click me' console.log and the link changes to /service/app/sort, but it's still the <MainPage />. If I click it one more time, I get the warning
"Warning: Hash history cannot PUSH the same path; a new entry will not be added to the history stack"

You're probably facing this problem because the start of the URL is being interpreted as truthy by react-router-dom, and is letting you access the /service/app anyway.
For example, the /service/app route will not only detect this route, but will also detect /service/app/1 or /service/app1 just because it has /service/app in the path.
To prevent this, you need to pass the exact property to the route, so react-router will understand that you need to access exactly this route to render that component.
<Route path="/service/app" exact={true}>
<MainPage />
</Route>

Related

React Route render blank page

Here is the code screenshot.
I want to render Homepage component but I want to wrap it into these MainLayout component.
The problem is that screen is blank and there is no error in Terminal but when I inspect the page it says "Matched leaf route at location "/" does not have an element", so guys I know this is version update syntax problem because I had same problem when I was writing component= {component } but syntax has been changed and I should have written element={<component />}.
So I believe this is also syntax problem but I've done research but couldn't solve. I believe I should change this
/* ... */ render = {() => (
<MainLayout>
<Homepage />
</MainLayout>
)}
somewhat into newer syntax but don't know how.
The Route components in react-router-dom v6 no longer take component or render props; the routed components are rendered on the element prop as JSX.
<Routes>
...
<Route
path="/"
element={(
<MainLayout>
<Homepage />
</MainLayout>
)}
/>
...
</Routes>

React Router change the link but can't changed the body

React router Link tag wokred in the first page and page also changed but in the 2nd page have many link If i click on this link it can changed the link but not body how can i fix it...
Router code :
<Switch>
<Route exact strict path="/">
<Home />
</Route>
<Route exact strict path="/about/">
<About />
</Route>
<Route exact strict path="/channel/:title" component={withRouter(Dashboard)} />
</Switch>
</div>
</Router>
2nd page code
function Dashboard() {
const { title } = useParams();
return (
<div>
<Play
title={title}
/>
</div>
);
}
Passing some data via props
//this is <Play/> component code just showing here shortly
<Router>
<VideoPlayer
controls={true}
src={this.state.link}
poster={this.state.poster}
width={window.screen.width}
height={window.screen.height - (window.screen.width+100)}
/>
<Link to="/channel/Rtv">Rtv</Link>
</div>
</Router>
just showing a little part of this code...
please help me ...how can i fix the error
Full code is here:
https://gist.github.com/fahadali32/8643d33a2328c1375552e4ba7637fc92
withRouter's documentation mentions:
withRouter does not subscribe to location changes like React Redux’s connect does for state changes. Instead, re-renders after location changes propagate out from the <Router> component. This means that withRouter does not re-render on route transitions unless its parent component re-renders.
This is not the behavior you want, so you shouldn't use withRouter.
So you should replace the line
<Route exact strict path="/channel/:title" component={withRouter(Dashboard)} />
with
<Route exact strict path="/channel/:title" component={Dashboard} />
If you need to access match or location or history, use the corresponding hook. You're already using useParams; you could also use useLocation or useHistory if you need them.
Ok i find the answer just simply add
<div key={this.props.link}>
<VideoPlayer controls={true} src={this.state.link} poster={this.state.poster} width={window.screen.width} height={window.screen.height - (window.screen.width+100)} />
</div>

redux is not updating states in component

From below code ,if i remove routes variable from code1 and go with code2 code than
i did not face any problem .but if i comment code2 routes variable and work with the code1
than i am facing problem that when i click on submit button of Auth.js file or /auth route
(without or with selecting any ingredient from /burgerBuilder route.
when user click on submit button of Auth.js file .it will dispatch auth action in redux store
than that will dispatch authStart than after receiving response from firebase than we dispatch authSuccess which changes token and some other data in redux.
than this changes will rerender all component who has auth object state in their mapStateToProps.but token is not updating in mapStateToProps in Auth.js file
where am i wrong .
complete code you can check on below link
[1]: https://codesandbox.io/s/goofy-kowalevski-mos8f?fontsize=14&hidenavigation=1&theme=dark
but i am getting problem when i conditioned routes in App.js file. if i dont do that than it works fine more i have already described in App.js file with code as well.
class App extends Component {
render(){
//console.log("App.js");
//code1::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
let routes ;
routes = (
<Switch>
<Route path="/auth" component={Auth}/>
<Route path="/" exact component={BurgerBuilder} />
</Switch>);
if(this.props.token)
{
routes = (
<Switch>
<Route path="/checkout" component={Checkout} />
<Route path="/orders" component={Orders} />
<Route path="/logout" component={Logout} />
<Route path="/" exact component={BurgerBuilder} />
</Switch>);
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//code2:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
routes = (
<Switch>
<Route path="/auth" component={Auth}/>
<Route path="/checkout" component={Checkout} />
<Route path="/orders" component={Orders} />
<Route path="/logout" component={Logout} />
<Route path="/" exact component={BurgerBuilder} />
</Switch>);
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
return (
<div>
<Layout>
{routes}
</Layout>
</div>
);
}
componentDidMount() {
this.props.onAuthCheck();
}
}
const mapStateToProps = (state)=>{
return {
token:state.auth.token
}
}
const mapDispatchToProps = (dispatch) => {
return{
onAuthCheck:() =>dispatch(authCheckState()) //when try to auto signin
}
}
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(App));
what i have already tried -> i have followed a question on stackoverflow that was telling that is because of unupdated react and react-dom .i am stuck in it from 12 hours .
thanks in advance.
i already mentioned that when i got the problem in question .when user was submitting the form it causes rerendering because of i received token from a server using an auth action.and i have conditioned my routes in such a way that it does not contain auth.js file (login/signup) page route. so that now it(auth.js) does not render because i omitted route of auth.js file(login/signup page).and even i have logged in and successfully received token but was still on the same url because the redirection code that i have written inside auth.js file does not execute.
some more information and refrence more clarity .-->
i known Link or NavLink component is related to Route .
but how it actually related
but actually what happening is .link component is internally an anchor tag when you click on that it changes your url .if your url changes mean it is changing your url property of match property of prop object.and in react we know if any prop changes it causes re-rendring.when it re-render the corresponding route whose path matches with the url render the component in its component props.
//////////////////////////////////////////////////////////////////////////////////////////
from react-router documentation .
Route Matchers-->
There are two route matching components: Switch and Route. When a is rendered,{*** it searches through its children elements to find one whose path matches the current URL. When it finds one, it renders that and ignores all others***}. This means that you should put s with more specific (typically longer) paths before less-specific ones.
If no matches, the renders nothing (null).
//////////////////////////////////////////////////////////////////////////////////////////

Why is React onLeave={} being executed for every single page switch, instead only in the assigned one?

I have this route that I want to have some stuff executing when the user leaves it.
So I found the onLeave hook
<Switch>
<Route exact path="/layout" onLeave={ console.log("LEFT LAYOUT") } render={(props) => <GridLayoutApps retracted={this.state.sideBarRetracted} {...props}/>} />
</Switch>
Its supposed to console.log "Left layout" whenever I'm in /layout, and decide to load another route. Point is, this doesn't seem to happen, since the console.log is loading each time I switch ANY route.
I have the routes in my app.js file, which I
export default withRouter(App);
I have encapsulated it like this in index
ReactDOM.render(<BrowserRouter><Provider store={store}><App /></Provider></BrowserRouter>, document.getElementById('root'));
onLeave needs to be a function. At present its just an normal prop
<Switch>
<Route exact path="/layout" onLeave={() => {console.log("LEFT LAYOUT")} } render={(props) => <GridLayoutApps retracted={this.state.sideBarRetracted} {...props}/>} />
</Switch>
However please note that onLeave is not longer available in react-router v4 onwards and you need to use the componentWillUnmount or the useEffect hook to trigger the same behaviour

How to create a route which points to a component in react

I have a table which is as shown below
I have a component which displays the details
How to display the details when click on the first tab of the table
i.e, when clicked on the number 1053 in the first column how to redirect to component with the parameter
Not sure how to build the route localhost:3000/#/sitepage/1053
Is there a way to directly get the route localhost:3000/#/sitepage/1053 so that i can give in the href of the table
Read about https://www.tutorialspoint.com/reactjs/reactjs_router.htm
but not sure how this link to route to write
Please point me to a document which will help me in doing
It you want to redirect to another component, you can use React Router Redirect
This section of React Router documentation will help you, since you haven't posted any code you tried I assumed you're looking for just some documentation to guide you.
Update:
Ok let's assume you have a Router like that:
<Router>
<Route exact path="/" render={(props) => <Table {...props} />}/>
<Route exact path="/column-details/:id" render={(props) => <ColumnDetails {...props} />}/>
</Router>
The props here has a history attribute, so in your <Table> you can have access to it by initializing your component like this
function Table({history}) {
// ...
}
Now in the first column, you need to add an onClick listener, let's say you use <TableCell> that would be
<TableCell onClick={() => history.push(`/column-details/${yourId}`)}/>
Now in your <ColumnDetails> component, we will need access to match attribute to extract our id from the url, so it would be something like:
function ColumnDetails({match}) {
const id = match.params.id;
// ...
}
I hope this is clear enough.
I think you can try react-router-dom to solve your problem, react-router-dom is a wrapper on top of react-router, which brings more flexibility
Let say your table is under Equipments component, then you have to add <Link/> component as alternate to <a> as follows, assuming your equipment object got url and title property
<Link to={`${equimpement.url}`}>{equimpement.title}</Link>
Please note that if you want to use Link component you have to import it on top
import { Link } from "react-router-dom";
And you can manage your routing in your App.js like this way
<div className="content">
<Switch>
<Route path="/not-found" component={NotFount} />
<Route path="/equipments/:id" exact component={EquipmentForm} />
<Route path="/equipments" component={Equipments} />
<Route path="/" exact component={Home} />
<Redirect to="/not-found" />
</Switch>
</div>
Make sure you have imported Route, Redirect and Switch as well in your on top of your App.js
import { Route, Redirect, Switch } from "react-router-dom";
Update
And last if you want to use Route in your app you must wrap your with BrwoserRouter
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
with its import import { BrowserRouter } from "react-router-dom";

Resources