React route not matching query string - reactjs

I want react route to match for localhost:8945/?type=admin adddress.I tried with following code but it is always rendering Home component.
<BrowserRouter>
<Switch>
<Route exact path = "/?type=admin"> **this is not working**
<Admin />
</Route>
<Route exact path = "/">
<Home/>
</Route>
</Switch>
</BrowserRouter>
Whenever I type localhost:8945/?type=admin in url bar it should render Admin component (Without requiring any server api).

got solution !
class App extends React.Component{
constructor() {
super();
this.state = {
type:''
};
}
componentDidMount() {
this.setUrlParams();
}
setUrlParams(){
const urlParams = new URLSearchParams(window.location.search);
this.setState({type : urlParams.get('type')})
}
render(){
return {
<div>
{ this.state.type=== 'admin'
? <Admin/>
: <Home/>
}
</div>
}
}
}

Hi, check this out Query Params

Related

ReactJS How to use Router's props inside app.js file

The app.js file of my project is following. For all other components I used this.props.history.push('/') to redirect to the specific path and it works as those components receives the props. But in this app.js I have tried to console the props values inside constructor, componentWillMount and render but all gives null array. Is there any way to use this.props.history.push('/') inside app.js ?
class App extends Component {
constructor(props) {
super(props);
this.state = {};
console.log(this.props)
}
componentWillMount(){
console.log(this.props)
this.props.history.push('/')
}
render() {
console.log(this.props)
return (
<Router>
<div className="App">
<Route exact path='/' render={(props) => <Login {...props} />} />
<Route exact path='/dashboard' render={(props) => <Dashboard {...props}/>}/>
</div>
</Router>
);
}
}
export default App;
use withRouter
import { withRouter } from 'react-router-dom'
class App extends Component {
constructor(props) {
super(props);
this.state = {};
console.log(this.props)
}
componentWillMount(){
console.log(this.props)
this.props.history.push('/')
}
render() {
console.log(this.props)
return (
<Router>
<div className="App">
<Route exact path='/' render={(props) => <Login {...props} />} />
<Route exact path='/dashboard' render={(props) => <Dashboard {...props}/>}/>
</div>
</Router>
);
}
}
export default withRouter(App);
that will give you access to the history object and allow you to push to new routes. (I tested and verified before posting, so I know this works).
import it on the top of the file, then wrap App with it in the export default

React Router v4 prevent from running parent route component

I'm building an article search with React [15.6.1] and Router [4.1.1] and noticed that when trying to access an article directly the previous component is loaded, even thou it's not the one that's being called
// === Layout ==================
class Layout extends React.Component {
render() {
return (
<Provider store={this.props.store}>
<HashRouter>
<div>
<Switch>
<Route exact path="/" component={SearchFilter} />
<Route path="/article/:guid" component={Article} />
</Switch>
</div>
</HashRouter>
</Provider>
);
}
}
// === SearchFilter ==================
class SearchFilter extends React.Component {
componentDidMount() {
console.log('SearchFilter Did Mount');
}
render() {
return (
<div>...</div>
);
}
}
// === Article ==================
class Article extends React.Component {
componentDidMount() {
console.log('Article Did Mount');
}
render() {
return (
<div>...</div>
);
}
}
So when going to the root localhost:3000/#/ it prints
// SearchFilter Did Mount
And when I access an article directly like this localhost:3000/#/article/123456 it prints
// SearchFilter Did Mount
// Article Did Mount
So my question is, how can I prevent it from running the previous route?
Because I would like to dispatch some actions there that would trigger some ajax calls to the webservice.
Thanks
Try this instead :
<HashRouter basename="/">
<div>
<Switch>
<Route exact path="/search" component={SearchFilter} />
<Route path="/article/:guid" component={Article} />
</Switch>
</div>
</HashRouter>
Edit:
For me its working well... So like said... there is something really weird and hidden happening on your machine, or you just put / and then rewrite url to /#/article/123 and it cause the first log stays in the console, but its from the previsous url "/" and if you reload the browser by F5 on the new url /#/article/123 you will see only the "Article did mount"

How to change routes from a component rendered by a <Route> in React?

I am rendering a Home component inside a Route so that I can pass state in as a prop to the component.
class App extends React.Component {
constructor(props){
super(props)
this.state = {
page: 'false'
};
}
render() {
return (
<Router>
<div>
<Switch>
<Route exact path='/' render={()=><Home page={this.state.page}/>} />
<Route exact path='/projects' component={Projects} />
<Route render={function(){
return <p>Not Found</p>
}} />
</Switch>
</div>
</Router>
)
}
}
Inside the Home component, I want to trigger a route change from a function. Because the Component is rendered inside the Route the history prop doesn't get passed in and therefore I cannot trigger a route change like so:
class Home extends React.Component{
constructor(props){
super(props);
this.gotoProjects = this.gotoProjects.bind(this);
}
gotoProjects() {
this.props.history.push('/projects');
}
render() {
return (
<button onClick={this.gotoProjects.bind(this)}>Projects</button>
)
}
}
How can I change routes from a component while still retaining it's props?
UPDATE
I've created a History.js using createBrowserHistory
import { createBrowserHistory } from 'history'
export default createBrowserHistory()
And updated App.js to be
import history from '../history';
class App extends React.Component {
constructor(props){
super(props)
this.state = {
page: 'false'
};
}
render() {
return (
<Router>
<div>
<Switch>
<Route exact path='/' render={()=><Home history={history} page={this.state.page}/>} />
<Route exact path='/projects' component={Projects} />
<Route render={function(){
return <p>Not Found</p>
}} />
</Switch>
</div>
</Router>
)
}
}
So now when I click the button in Home the url goes to /projects but the view is still rendering Home instead of Projects. How do I render Projects after the history.push happens?

React setState does not set the state

I am doing a simple react application and I have an App component which keeps track of the state and then renders it. At first the state it is an empty string. Afterwards when I access the /signin I click on a button that changes the state from "" to "Marc" and pass it via props to the Profile component who renders the name of the user on its page. The problem is that it does not change the state and it is always "". I tried to debug and the state is always "" but the method setState is actually called. So i do not know why. Can anyone help me? Thanks in advance and I enclose the code.
APP:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
session: ""
};
this.updateUser = this.updateUser.bind(this);
}
updateUser() {
this.setState({
session: "Marc"
});
}
render() {
return(
<BrowserRouter>
<Switch>
<Route path exact='/' component={Home}/>
<Route path='/profile' render={(props) => (
<Profile session={this.state.session} />
)}/>
<Route path='/signin' render={(props) => (
<SignIn onClick={this.updateUser} />
)}/>
</Switch>
</BrowserRouter>
);
}
}
SIGNIN:
export default class SignIn extends React.Component{
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
responseGoogle (googleUser) {
const mail = googleUser.profileObj.email;
const familyName = googleUser.profileObj.familyName;
const name = googleUser.profileObj.name;
//this.changeName(mail);
alert("Mail: " + mail + "\n" + "Nom i Cognoms: " + name + "\nSuccessfully Logged In");
}
handleClick() {
this.props.onClick();
}
render () {
return (
<div>
<GoogleLogin
clientId="CLIENTID"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
buttonText="Google"/>
<button onClick={this.handleClick}>Instant User</button>
</div>
);
}
}
PROFILE:
export default class Profile extends React.Component {
constructor(props) {
super(props)
}
render() {
return(
<h1>I am {this.props.session} User</h1>
);
}
}
In your case when at the SignIn component, onClicking the button will update the State correctly, but when you try to visit another page say Profile by manually entering the URL in browser, your state change will be lost and the state will be reinitialized as you session has changed.
You should instead try to navigate Programatically , for which you could refer the following answer on StackOverflow:
Programatically Routing based on a condition with react-router
In short In SignIn component you will have
class SignIn extends React.Component {
...
handleClick() {
this.props.onClick();
this.props.history.push('/profile');
}
...
export default withRouter(SignIn);
The above is what I will recommend you to do, or else for testing you can have a Link component and navigate using that
render() {
return(
<BrowserRouter>
<div>
<Link to="/profile">Profile</Link>
<Switch>
<Route path exact='/' component={Home}/>
<Route path='/profile' render={(props) => (
<Profile session={this.state.session} />
)}/>
<Route path='/signin' render={(props) => (
<SignIn onClick={this.updateUser} />
)}/>
</Switch>
</div>
</BrowserRouter>
);
}

this.props.params not existing after passing parameter on react-router

I'm passing parameter from react-router's route path to component but in this.props object, 'params' not existing
const routes = (
<Router forceRefresh={true}>
<div>
<Route exact path="/" component={Firstpage}/>
<Route exact path="/projects" component={Projectslist}/>
<Route exact path="/projects/:projectId" component={Singleproject}/>
</div>
</Router>
);
And this is my component:
class Singleproject extends React.Component{
constructor(props) {
super(props);
}
componentWillMount(){
window.document.title = "Wploper | Project title";
}
render(){
return(
<div>
<Mainheader/>
<div id="single-project-container" className="sheet-max-width">
<h2>{this.props.params}</h2>
</div>
<Mainfooter/>
</div>
);
}
}
And the object (this.props) hasn't params:
enter image description here
tested for react-router v4
in your Singleproject component you can get the params by :
this.props.match.params.projectId
below is a code sample :
class ForgotPassword extends Component {
constructor (props,context){
super(props,context);
this.state={
busy : true,
sessionId : localStorage.getItem('sessionId') || null,
resetKey : this.props.match.params.resetKey || ''
};
console.log(this);
}
}
In react-router version 4 you can get the path params with this.props.match.params
You can get the parameter from the route through context.
this.context.params.projectId

Resources