having issue with Route & Link in react-router-dom - reactjs

I am working on a React project in which I use the Switch, Link and Route from react-router-dom to route to the paths. but now I'm facing an issue and in console I'm getting errors The context router is marked as required in Link, but its value is undefined and cannot read property history of undefined which is pointing to Link.js line number 76 . When i checked Link.js, there is a line where this.context.router.history is used, and seems like this.context.router is undefined. Couldn't figure out whats the real issue as this was working till yesterday. The version of react-router-dom I'm using is 4.1.1.

Can you provide some code example?
It seems like you are putting outside of BrowserRouter's scope (or HashRouter's).
must always be inside the scope of .
You can do this:
<BrowserRouter>
<Link ... />
<Layout>
<Switch>
<Route ... />
<Route ... />
<Route component={NotFound} />
</Switch>
</Layout>
</BrowserRouter>`
But you cannot do something like this:
<Link ... />
<BrowserRouter>
<Layout>
<Switch>
<Route ... />
<Route ... />
<Route component={NotFound} />
</Switch>
</Layout>
</BrowserRouter>`
User Kishan Jaiswal is pointing you in the right direction by the way, he's linking to an issue which wasn't a bug but only a misplaced Link component outside of react-router-dom Router.

just take a reference of this and match your route file
https://github.com/ReactTraining/react-router/issues/4759

Related

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>

react-router-dom Prompt never shows

I have a React Route with significant user input that I want to use the Prompt component with. I'm importing it from react-router-dom without error and adding the component to the render method of the class component, but no matter what, the prompt alert never actually appears and the user can freely navigate off the page without seeing any alert.
I've tried:
Putting the component in with when={aStateBooleanVariable} as well as when={true} and no when attribute at all.
Using a function for the message.
Ensuring that the Route it's on is an exact path.
Importing it from react-router instead of react-router-dom.
Moving the component around within the render method.
Moving the Prompt into the actual Switch statement itself in the App component that wraps everything in BrowserRouter.
Nothing I've tried has gotten the prompt to actually show up or prevent the user from navigating off the page and I've been unable to find anything in the docs or extensive searching where anyone else has had this problem. Does anyone have any idea why this just isn't even starting to work?
I'm not really sure what code to put since it's all pretty much boilerplate react-router-dom.
This is my App.jsx switch statement:
return (
<BrowserRouter>
<header>
{loggedInUser ? <NavbarComp loggedInUser={loggedInUser} setLoggedInUser={setLoggedInUser} /> : null}
</header>
<Switch>
<PrivateRoute path="/ged/campaigns/new" component={CampaignNew} loggedInUser={loggedInUser} />} />
<PrivateRoute path="/ged/campaigns/:id" component={Campaign} loggedInUser={loggedInUser} />} />
<PrivateRoute path="/ged/characters/new" component={CharGen} loggedInUser={loggedInUser} />} />
<PrivateRoute path="/ged/characters/:id" component={CharacterMain} loggedInUser={loggedInUser} />} />
<PrivateRoute path="/ged" component={GEDHome} loggedInUser={loggedInUser} />} />
<Route path="/" component={Home} loggedInUser={loggedInUser} setLoggedInUser={setLoggedInUser} />} />
<Route component={DeadPage} />
</Switch>
</BrowserRouter>
)
I'm importing the component as:
import {Prompt} from 'react-router-dom';
And incorporating the component at the top of its parent's render method return:
<Prompt message="You have changes that will be lost if you leave without saving." />
What other code might be making it fail silently like this?

React Router v4 rendering component twice

Here is my Router Implementation
<BrowserRouter>
<div>
<Route exact path="/" component={ProfilesIndex} />
<Route exact path="/profiles" component={ProfilesIndex} />
<Route exact path="/profiles/new" component={ProfileEditor} />
<Route exact path="/profiles/:id" component={ProfileEditor} />
</div>
</BrowserRouter>
When I am browsing to /profiles/new path, it is rendering the ProfileEditor component twice. For every other route, it is working fine.
Can someone suggest how to fix this problem ?
I found the answer after browsing into multiple sections in Router Docs. Problem was it was matching multiple routes
When user opens /profiles/new it matches two routes
/routes/new
/routes/:id
Because :id is like a wildcard * and it also matches new word so both routes get matched and hence the component gets rendered twice.
The solution is to wrap the routes with Switch if you do not want to match multiple routes.
<BrowserRouter>
<Switch>
<Route exact path="/" component={ProfilesIndex} />
<Route exact path="/profiles" component={ProfilesIndex} />
<Route exact path="/profiles/new" component={ProfileEditor} />
<Route exact path="/profiles/:id" component={ProfileEditor} />
</Switch>
</BrowserRouter>
For anyone coming here from v6+
exact prop no longer exists, the paths are exact by default if they aren't appended a wildcard *
However I was still getting a double render. I ran a prod build and checked and the double render is gone so probably nothing to worry about - sometimes hooks run twice in development mode (I guess that's what's happening internally)
for me, this is because of React.StrictNode which is wrapped arround App component.
it intentionally double render components (only in development) to enforce you, not use side effects on some of your component's
lifecycle events.
the reason behind that is documented here

Reactjs - React Router disallowing paths

I have a route
<Route exact path="/view/:personID" component={PersonView} />
It works fine, however /view still renders, albeit with no person in it. Is there a way to disallow this path or turn in into a 404?
Answer was to use switch
<Switch>
<Route exact path="/view/:personID" component={PersonView} />
<Redirect from='/view' to='/' />
</Switch>
You can manage this on your component, in the render section test if you have your personID if not return a custom error/view.

Prefixing all react links within the app

I have several links throughout my react app that look like this:
<Route path="/linkpath" component={Whatever} />
or
<Link to="/linkpath">Click Me</Link>
Is there a quick/easy way to prefix all the links throughout the app with a predetermined string? ... perhaps via a Router configuration param?
So for example if my prefix is "/foo", all links to "/linkpath" would be converted to /foo/linkpath.
Note: Just to clarify, I'm using react-router-dom v4.0.0-beta.5
It turns out the Router in react-router-dom v4.0.0-beta.5 has a param called basename that addresses this scenario.
<Router basename="/foo">
<Link to="/linkpath">Click Me</Link>
<!-- other links here -->
</Router>
In this case, Click Me's link will be /foo/linkpath. So, as long as Router wraps all Components in the app, all links will be prefixed with basename.
One important note: Make sure the string in basename starts with a slash; i.e., use "/foo" instead of "foo". The latter one produces undesired behavior when clicking links (it appends the full link path to the existing URL everytime you click the link, instead of replacing it).
Using React Router, if you defined your routes using nesting like this:
<Router history={history}>
<Route path="/" component={App}>
<Route path="/hello" component={Hello} />
<Route path="/whatever" component={Whatever} />
</Route>
</Router>
Then you can simply change the path of the outermost Route component and it will add the prefix. In the case above, you could change it to:
<Router history={history}>
<Route path="/api" component={App}>
<Route path="/hello" component={Hello} />
<Route path="/whatever" component={Whatever} />
</Route>
</Router>
And then all the nested routes will be at /api/hello, /api/whatever instead of the original /hello and /whatever.

Resources