react router onChange - javascript

How to pass new props when route changed?
I need change class depends on route.
export class Routes extends React.Component<any, any> {
constructor(props:any){
super(props);
}
handleChange = (prevState, nextState, replaceState) => {
console.log(nextState.location.pathname);
};
render(){
return(
<Router {...this.props}>
<Route path="/" onChange={this.handleChange} component={Miramir}>
<Route path="/about">
<IndexRoute component={Miramir}></IndexRoute>
</Route>
<Route path="/contact">
<IndexRoute component={Miramir}></IndexRoute>
</Route>
<Route path="/profile">
<IndexRoute component={Profile} />
<Route path="/profile/update" component={ProfileUpdate} />
<Route path="/profile/login" component={LogInPage} />
</Route>
</Route>
</Router>
)
}
}
I'm trying to get props in my Miramir component and check location.pathname
For example: On my route / i want header class home-page and on /profile route want profile-page class.
But when i change routes location.pathname has / route
How to check update props?
I need nextState.location.pathname in my Miramir component

You can provide onEnter hook when route is about to change.
e.g
<Route
path="/profile/update"
component={ProfileUpdate}
onEnter={onProfileUpdate}
/>
Then you can define that function onProfileUpdate
function onProfileUpdate(nextState, replace, callback) {
replace({
pathname: '/transition path name here',
state: { nextPathname: nextState.location.pathname }
});
}

If your component is a route component, like it is in your case, it will get some props injected into it by the Router itself. You'll get your current location, params and so on, so you could simply read that in your render method and act accordingly.
https://github.com/ReactTraining/react-router/blob/master/docs/API.md#injected-props
If you need to access something in a component living deeper in your tree, you could wrap it with the withRouter HOC.
https://github.com/ReactTraining/react-router/blob/master/docs/API.md#withroutercomponent-options

Related

Passing props in React Route component for "react-router-dom": "^5.2.0"

I'm using "react-router-dom": "^5.2.0".
I simply want to pass props to Child components Like this
note: this is pseudo-code:
<Route exact path="/databases/buyordersdata" component={BuyOrders param1={value1}} />
This is the React file:
class Databases extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route exact path="/databases/" component={Navigation} />
<Route exact path="/databases/makebuy" component={MakeBuy} />
<Route exact path="/databases/makesell" component={MakeSell} />
<Route exact path="/databases/buyordersdata" component={BuyOrders} />
<Route exact path="/databases/sellordersdata" component={SellOrders} />
<Route exact path="/databases/AllMyOrders" component={MyOrders} />
</Switch>
</BrowserRouter>
</div>
)
}
}
const element = <Databases />;
ReactDOM.render(element, document.getElementById('contents'));
Solution
In parent component
<Route exact path="/databases/buyordersdata" render={
(props) => <BuyOrders {...props} order_type={true}/>
}/>
then in Child component
class BuyOrders extends Component {
constructor(props){
super(props)
}
...
render() {
console.log(this.props.order_type)
You just do something like this: Instead of using the route component like that, you can use the Route component as a parent and the component itself as a child.
<Route exact path="/path">
<BuyOrders param1={value1} /> // Then pass the props like that
</Route>

withRouter Does Not passes Route props to component

Here is my navigation component:
import React from 'react'
class Navigation extends React.Component {
constructor(props) {
super(props);
this.state = {
type: 'signUp', // or login
showModal: false,
isLoggedIn: false,
}
}
...some code
render() {
const { showModal, type, isLoggedIn } = this.state
console.log(this.props.location); // all problem is this, I'm not getting it in console
return(
...some more code
)
}
}
export default withRouter(Navigation)
And here is where it it been used in app.js
class App extends React.Component {
render () {
return(
<Router>
<Fragment>
<Navigation /> // <= right there
<Switch>
<Route exact path='/' component={HomePage}/>
<Route exact path='/search' component={HomePage}/>
<Route component={Lost} />
</Switch>
</Fragment>
</Router>
)
}
}
I want to get updated route props like match and location and history in my <Navigation /> component but I get it only when the first time that component mounts on the DOM, in my other components I update the route using window.history.pushState but I am not able to get route props from withRouter after link in the browser is been updated.
I update route with window.history.pushState because:
I could not find any way to update just link in the address bar without showing user or redirecting user to new component with React router DOM (am I doing it in right way or not?)
based on that I then use window.location.pathname to add some specific stylings to some components)
Also, I read the entirety of this and this but I could not solve this issue. What am I doing wrong?
withRouter gives you the closest <Route>'s route props, and since the Navigation component is not inside a Route you will not get the route props.
You could e.g. put the Navigation component on a Route outside of the Switch that will always be visible.
Example
class App extends React.Component {
render() {
return (
<Router>
<Fragment>
<Route path="/" component={Navigation} />
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/search" component={HomePage} />
<Route component={Lost} />
</Switch>
</Fragment>
</Router>
);
}
}

`react-router` warning solution and passing root props to sub routes

Sometime I was sawing the well known warning, browser.js:49 Warning: [react-router] You cannot change <Router routes>; it will be ignored and I found two trend issues that friends discussed about this issue and the solution is const routes components and putting them inside Router component.
https://github.com/ReactTraining/react-router/issues/2704
https://github.com/reactjs/react-router-redux/issues/179
Just like below:
you will see warning with this code:
class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
</Router>
)
}
}
but you won't see warning with this code:
const routes = (
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
);
class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
{routes}
</Router>
)
}
}
This is OK, awesome solution to vanish [react-router] warning, and for Root Component changing state the routes was static and you won't see any warnings. BUT my issue is: I pass Root Component props to each Route and I can not do the above solution 😞 ,
I must put App Route inside Router so with this method absolutely this is not solution method and I will saw the known warning again, see my router code:
export default class AppRoutes extends Component {
render() {
return (
<Router history={hashHistory}>
<Route path="/" {...this.props} component={App}>
<IndexRoute component={Home} {...this.props}/>
<Route path="/transaction" component={Transaction} {...this.props}/>
<Route path="/users-management" component={UsersManagement} {...this.props}/>
<Route path="/issues" component={Issues} {...this.props}/>
<Route path='/not-found' component={NotFound}/>
<Route path='/settlement-management' component={SettlementManagement} {...this.props}/>
<Route path='/categories-management' component={CategoriesManagement} {...this.props}/>
<Route path='/gifts-management' component={GiftsManagement} {...this.props}/>
<Redirect from='/*' to='/not-found'/>
</Route>
</Router>
);
}
}
And the Root Component render code is:
render(){
return(
<AppRoutes {...this}/>
);
}
I passed this as a props to AppRoutes component and I need to pass inherited this.props to sub Routes and use them. how I could won't see warning and pass props to any Routes?
One of my solution is that, I write all Routes as static and call Root Component props directly inside each component, but how? I don't know how I can call and keep props of Root Component inside the component that need to have props of Root Component as the component is not direct Root Component children?
You can use render route prop instead of component to pass props to your components :
<Route path="/transaction" render={() => <Transaction {...this.props} />} />
Edit : Or this to also pass route props :
<Route path="/transaction" render={(routeProps) => <Transaction parentProps={this.props} {...routeProps} />} />
(I think it's better to pass individual custom parent props to not enter in conflict with routeProps)

Accessing parent state in child in React

I have (e.g.) two components in React. The first, app.js, is the root component. It imports some JSON data and puts it in its state. This works fine (I can see it in the React devtools).
import data from '../data/docs.json';
class App extends Component {
constructor() {
super();
this.state = {
docs: {}
};
}
componentWillMount() {
this.setState({
docs: data
});
}
render() {
return (
<Router history={hashHistory}>
<Route path="/" component={Wrapper}>
<IndexRoute component={Home} />
<Route path="/home" component={Home} />
<Route path="/docs" component={Docs} />
</Route>
</Router>
);
}
}
The second, docs.js, is meant to show this JSON data. To do that it needs to access the state of app.js. At the moment it errors, and I know why (this does not include app.js). But how then can I pass the state from app.js to docs.js?
class Docs extends React.Component {
render() {
return(
<div>
{this.state.docs.map(function(study, key) {
return <p>Random text here</p>;
})}
</div>
)
}
}
The proper way of doing this would be by passing state as props to Docs component.
However, because you are using React Router it can be accessed in a bit different way: this.props.route.param instead of default this.props.param
So your code should look more or less like this:
<Route path="/docs" component={Docs} docs={this.state.docs} />
and
{this.props.route.docs.map(function(study, key) {
return <p>Random text here</p>;
})}
Another way of doing this is:
<Route path="/docs" component={() => <Docs docs={this.state.docs}/>}>
If you need to pass children:
<Route path="/" component={(props) => <Docs docs={this.state.docs}>{props.children}</Docs>}>
If you are doing it like this, then you can access your props values directly by this.props.docs in Child Component:
{
this.props.docs.map((study, key)=> {
return <p key={key}>Random text here</p>;
})
}
Another way of doing this will be
<Route path='/' render={ routeProps => <Home
{...routeProps}
docs={this.state.docs}
/>
}
/>
While in the child component you can access docs using
this.props.docs
Hope it helps!

How to get the prams value over the link router in react

I have this link in main component how to get the value in the player component:
<Link to="/player" params={{ testvalue: "hello" }}
className="btn">watch</Link>
class Player extends React.Component{
render(){
alert(this.params.testvalue);
return(
<div></div>
);
}
}
This is a route file
<Route path="/" component={App}>
<IndexRoute component={main}/>
<Route path="/player" component={Player}/>
</Route>
with react router it passes a location object down as props, should be able to access the query using
this.props.params.testvalue
in you Player component
The problem with your code is that you are passing a param with
<Link to="/player" params={{ testvalue: "hello" }}
className="btn">watch</Link>
but you are not receiving it in the Route. Change you route like
<Route path="/" component={App}>
<IndexRoute component={main}/>
<Route path="/player/:value" component={Player}/>
</Route>
Then use
this.props.params.testvalue
in your Player component.

Categories

Resources