React navigation to pages issues - reactjs

I am trying to navigate to a login page using react router but when the button is clicked, the next page is displayed on the same page without actually navigating to the next page.
Here is my code
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import $ from 'jquery';
import { Login } from './Login';
export class Index extends Component {
render() {
return (
<div>
<div align='center'>
<h3> Project Management System </h3>
</div>
<p>
Here, you can search for the previous B.sc, M.sc and Ph.D projects that have been carried out in the department. <br/><br/>
</p>
<Router>
<div>
<Link to="/login">Continue </Link>
<Route exact path={"/login"} component={Login}/>
</div>
</Router>
</div>
);
}
}
When I click on continue button, it's supposed to show the login page alone, without showing the previous page, but here, it shows both previous page and the login page.

--Edit--
Move your button and info in another Component, call it Home or something similar.
Home.js
import React from "react"
import { Link } from "react-router-dom"
const Home = () => {
return(
<div>
<div style={{textAlign: "center"}}>
<p>Your paragraph</p>
<Link to="/login">Continue </Link>
</div>
</div>
)
}
export default Home
Index.js
now you'll have a cleaner Router
keep all your imports and bring in the Home component
export class Index extends Component {
render() {
return (
<div>
<Router>
<div>
<Switch>
<Route path="/" exact={true} component={Home}>
<Route path="/login" component={Login}/>
</Switch>
</div>
</Router>
</div>

The reason for that behavior is very simple. You wrapped only Login component with the router. You have to create routes with the Switch component to change the views. Here is an example https://codesandbox.io/s/2xqxqpo550

Related

Both Pages are Displaying its content on a single page - React

Hey I am a Smart Contract Developer first time using react and when I try to switch pages using Router both pages Data are showing on a single page, I wanna ask is there some way to first load main page and when I click on another button the data of another page show.
App.js:
<Router>
<Link className="btn-success user-btn" to = "/user">User Login</Link>
<Link className="btn-success admin-btn">Admin Login</Link>
<Switch>
<Route path={"/user"} exact>
<User />
</Route>
</Switch>
</Router>
User.js:
import React from 'react';
const User = () =>{
return(
<div>
User Panel
</div>
);
}
export default User;
App Component is the main component in React which acts as a container for all other components. When you put some content in there, it will show up everywhere in your app. You can simply create another component, let's name it Home
Home.js
import React from 'react';
import { Link } from 'react-router-dom';
const Home = () =>{
return(
<div>
<Link className="btn-success user-btn" to = "/user">User Login</Link>
<Link className="btn-success admin-btn">Admin Login</Link>
</div>
);
}
export default Home;
App.js
import User from './User';
import Home from './Home';
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path={"/"} component={Home}></Route>
<Route exact path={"/user"} component={User}></Route>
</Switch>
</Router>
</div>
);
}
export default App;

React-router URL changes but page is still unchanged

I am new to react and react-router, so please go easy on me.
I am trying to implement router in my Todo List project, where path="/" takes me to my todo list and path="/id" takes me to a test page (later will show the description of the task).
When I click the link that takes me to "/id", the URL in the browser changes but the page/content doesn't. However, when I refresh my browser, the test page loads.
I have put the Switch in App.js shown below.
import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";
class App extends Component {
render() {
return (
<Router>
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route exact path="/" component={TodoList} />
<Route path={`/id`} component={Test} />
</Switch>
</div>
</Router>
);
}
}
export default App;
And I have put the Link to "/id" as shown below in a child component of component which is called here in App.js.
<div key={todo.id}>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
</div>
Am I missing something which is causing my component to not load when I click the link?
Edit: Here's a link to my project. https://stackblitz.com/edit/react-7cpjp9?file=src/index.js
Issue
Ok, the issue is exactly as I had suspected. You are rendering multiple routers in your app. The first is a BrowserRouter in your index.js file, the second, another BrowserRouter in App.js, and at least a third BrowserRouter in Todo.js. You need only one router to provide a routing context for the entire app.
The issue here is that the router in Todo component is the closest router context to the links to specific todo details. When a link in Todo is clicked, this closest router handles the navigation request and updates the URL in the address bar. The blocks, or "masks", the router in App component or index.js that is rendering the routes from "seeing" that a navigation action occurred. In other words, the URL in the address bar is updated by the inner router, but the outer router doesn't know to render a different route.
Solution
Keep the BrowserRouter wrapping App in index.js and remove all other routers used in your app.
App - Remove the Router component. Also, reorder the routes/paths from most specific to least specific so you don't need to specify the exact prop on every route. Allows more specific paths to be matched and rendered before less specific paths by the Switch component.
class App extends Component {
render() {
return (
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route path="/id/:todoId" component={Test} />
<Route path="/" component={TodoList} />
</Switch>
</div>
);
}
}
Todo - Remove the Router component. Move the key={todo.id} up to the outer-most element so when todos array is updated React can reconcile updates.
class Todo extends Component {
constructor(props) {
super(props);
this.state = {
id: null,
value: "",
details: "",
};
this.submitUpdate = this.submitUpdate.bind(this);
}
submitUpdate(value) {
const { updateTodo } = this.props;
updateTodo(this.state.id, value);
this.setState({
id: null,
value: "",
});
}
render() {
const { todos, completeTodo, removeTodo } = this.props;
if (this.state.id) {
return <TodoForm edit={this.state} onSubmit={this.submitUpdate} />;
}
return todos.map((todo, index) => (
<div
className={todo.isComplete ? "todo-row complete" : "todo-row"}
key={todo.id}
>
<div>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
</div>
<div className="icons">
<RiCloseCircleLine
onClick={() => removeTodo(todo.id)}
className="delete-icon"
/>
<TiEdit
onClick={() => this.setState({ id: todo.id, value: todo.text })}
className="edit-icon"
/>
<RiCheckboxCircleLine
onClick={() => completeTodo(todo.id)}
className="delete-icon"
/>
</div>
</div>
));
}
}
First of all the approach, you are taking for dynamic routing is wrong.
It should be like this you will have to add the exact keyword on the dynamic route.
<Route exact path="/id/:todoId" component={Test} />
And
<div key={todo.id}>
<Link className="todo-text" to={`/id/${todo.id}`}>
{todo.text}
</Link>
import React, { Component } from "react";
import "./App.css";
import TodoList from "./components/TodoList";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Test from "./components/Test";
class App extends Component {
render() {
return (
<Router>
<div className="todo-app">
<p>
<Link to="/">Home</Link>
</p>
<Switch>
<Route exact path="/" component={TodoList} />
**<Route exact path={`/id`} component={Test} />**
</Switch>
</div>
</Router>
);
}
}
export default App;

The link is being rendered but not redirecting using <Link>

I have been trying to redirect the page using <Link> and what i have is that the URL changes but the page does not redirect. Only after i refresh the page, it show.
I have searched and found some links:
1. One on the correct syntax
2. i have implemented the link in small HTML
Now here is the part of my Code
App.Js
import React from 'react';
import { Switch , Route , BrowserRouter } from 'react-router-dom';
import HomePage from './section/home';
import Oneup from './section/oneup';
function App() {
return (
<div className="main homepage">
<BrowserRouter>
<div>
<Switch>
<Route path="/" component={HomePage} exact={true} />
<Route path="/oneup" component={Oneup} exact={true} />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
main_content.js
Here i have included <Link>
import React from 'react';
import { BrowserRouter, Link } from "react-router-dom";
class Main_content extends Component {
render() {
return (
<div class="ib-center">
<BrowserRouter>
<Link to="/oneup" class="btn">VIEW CASE</Link>
</BrowserRouter>
</div>
)
}
}
Now i can't figure out where i am going wrong.
the link generated is fine and working when refreshed manually.
Use one BrowerRouter to wrap, you have used BrowerRouter in App.js and main_content.js too
class Main_content extends Component {
render() {
return (
<div class="ib-center">
<div>
<Link to="/oneup" class="btn">VIEW CASE</Link>
</div>
</div>
)
}

Have a react app with routing and routes gives error on refresh.what could be the reason?

i have routing attribure in my react.js app. when i click on the route for the first time it works fine but if i refresh in the page it gives error saying cannot read property ... of null. I'm making api call from tmdb. Why i get error on refresh? Secondly, i have another route which i cannot access to it unless it is above the first route i mention. I mean when i put TvInfo above the MovieInfo tvinfo works movie info doesn't. This way only movieinfo works. If i click the above route elements first then clicking tvinfo element i get the previous clicked movie on the screen again. What could be the problem i tried many things? thanks
import React,{ Component } from 'react';
import Home from './components/Home';
import MovieInfo from './components/MovieInfo';
import TvInfo from './components/TvInfo';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
class App extends Component {
render(){
return(
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/:movie_id" component={MovieInfo} />
<Route path="/:tv_id" component={TvInfo} />
</Switch>
</BrowserRouter>
)
}
}
export default App;
You need to design your Routes a little differently, Route component cannot differentiate between two separate params.
class App extends Component {
render(){
return(
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="movie/:movie_id" component={MovieInfo} />
<Route path="tv/:tv_id" component={TvInfo} />
</Switch>
</BrowserRouter>
)
}
}
export default App;
this is my movieInfo component
class MovieInfo extends React.Component{
render(){
return(
<div>
<p style={{marginLeft:'47%',fontSize:25}}>{this.props.selectedMovie.original_title}</p>
<img style={{marginLeft: '20%'}}
src={`http://image.tmdb.org/t/p/w780${this.props.selectedMovie.backdrop_path}`} alt="moviebackdrop"/>
<div style={{float:'right',marginRight:45}}>
<p>Release Date: {this.props.selectedMovie.release_date}</p>
<p>Vote: {this.props.selectedMovie.vote_average}<Icon name="star" color="yellow" /></p>
</div>
<p style={{width:800,marginLeft: '20%'}} >{this.props.selectedMovie.overview}</p>
<p>{this.props.data.homepage}</p>
</div>
)}
}
const mapStateToProps = (state) => {
return{
selectedMovie:state.movie.selectedMovie,
}
}
to be able to display this screen i have another component where you show the images for the movies. when i click on the image it renders movieInfo component.
here is my image component.
selectMovie = () => {
this.props.setMovie(this.props.movie)
}
render(){
return(
<Link to={"movie/" + this.props.movie.id}>
<div onClick={() => this.selectMovie()}>
<div className="item">
<img className="img"
src={`http://image.tmdb.org/t/p/w342${this.props.movie.backdrop_path}`} alt="moviebackdrop"/>
<p className="title">{this.props.movie.original_title}</p>
<p className="overview">{this.props.movie.overview}</p>
</div>
</div>
</Link>
)}
}

Routes not working in react router v4

I am trying to work with react router v4. I have a application where I have two pages: Login page and App Page. In my app page I have three sections: Header, sidebar and content section. This is what I want
Landing page should be Login page
Once user clicks login button, user should land to App Page. (For testing I haven't included user authentication)
Now in my App page, I can show one of the 3 components (which I have already made) based on what user clicks on sidebar. So Sidebar and header should always be visible and content division should change it's component based on what user click on sidebar.
This is how I have setup my routes right now
class Root extends Component {
render() {
return (
<div>
<main>
<Route exact path="/" component={LoginPage} />
<Route exact path="/app" component={App}>
</Route>
</main>
</div>
);
}
}
And App.js
class App extends Component {
render() {
return (
<div>
<Header/>
<Sidebar/>
<main>
<Switch>
<Route exact path="/trivia" component={TriviaPanel}/>
<Route exact path="/image" component={ImagePanel}/>
</Switch>
</main>
</div>
);
}
}
MenuPanel.js (from where I go to trivia and image)
import React, { Component } from 'react';
import { push } from 'react-router-redux'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
const styles = require('./sidebar.css');
class MenuPanel extends Component {
render() {
return (
<div>
<div className="navbar-side">
<div className="tessact-logo"></div>
<div className="navbar-item active" onClick={() => this.props.toTriviaPage()}>
<a className="navbar-item-link"><span className="fa fa-comment"></span> TRIVIA</a>
</div>
<div className="navbar-item" onClick={() => this.props.toImagePage()}>
<a className="navbar-item-link"><span className="fa fa-picture-o"></span> IMAGES</a>
<div className="navbar-item-inside">
<a className="navbar-item-inside-link">PERSONSS</a>
<a className="navbar-item-inside-link">BRANDS</a>
<a className="navbar-item-inside-link">OBJECTS</a>
</div>
</div>
<div className="navbar-item">
<a className="navbar-item-link"><span className="fa fa-tags"></span> KEYWORDS</a>
</div>
</div>
</div>
);
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
toTriviaPage: () => push('/app/trivia'),
toImagePage: () => push('/app/image')
}, dispatch)
export default connect(
null,
mapDispatchToProps
)(MenuPanel)
I want TriviaPanel to be the default view when landed to App. Currently I land to login page and when I click to login, App page is not working in the manner it should. I can't see anything apart from sidebar and header, which also gets disappear when I click something in sidebar (trivia link).
How should I achieve this? In react router v3 there was a nice option of childroutes. What can I do to solve this?
The problem is in App. You are doing the nesting correctly, but your paths are wrong. Looking at Root the App component lives on /app. So your nested routes should ALSO include the /app prefix in their paths:
class App extends Component {
render() {
return (
<div>
<Header/>
<Sidebar/>
<main>
<Switch>
<Route exact path="/app/trivia" component={TriviaPanel}/>
<Route exact path="/app/image" component={ImagePanel}/>
{/* Catch-all route for TriviaPanel */}
<Route component={TriviaPanel}/>
</Switch>
</main>
</div>
);
}
}
Update:
Ah, apparently this is a known issue with react-router-redux: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/redux.md#blocked-updates
You need to wrap your connected component with the withRouter HOC from react-router-dom:
// before
export default connect(
null,
mapDispatchToProps
)(MenuPanel)
// after
import { withRouter } from 'react-router-dom'
export default withRouter(connect(
null,
mapDispatchToProps
)(MenuPanel))

Resources