I am new to React and I am trying to display a react route using react router dom but the matching component is not coming up. I have looked at answers from other OS questions related but no help. Here is my app.js file
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import AdminLogin from './AdminLogin';
export default class AdminApp
extends Component {
render() {
return (
<Router>
<Switch>
<div className="App">
<Route path="/" exact={true} component = {AdminLogin} />
</div>
</Switch>
</Router>
);
}
}
if (document.getElementById('app')) {
ReactDOM.render(<AdminApp />, document.getElementById('app'));
}
When i inspect my html file i get this
<div id="app">
<div class="App" location="[object Object]" computedmatch="[object Object]"></div>
</div>
this is my adminLogin component
import React, {Component} from 'react';
import {adminLogin} from './UserFunctions';
export default class AdminLogin extends Component {
constructor(){
super()
this.state = {
email: '',
password: '',
errors: {}
}
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e){
this.setState({ [e.target.name]: e.target.value })
}
onSubmit(e){
e.preventDefault;
const user = {
email : this.state.email,
password : this.state.password
}
adminLogin(user).then(res => {
if(res) {
this.props.history.push('/dashboard');
}
})
}
render(){
return (
<div className="kt-grid kt-grid--ver kt-grid--root">
<div className="kt-grid kt-grid--hor kt-grid--root kt-login>
<h1>Login Now</h1>
</div>
</div>
)
}
}
This only works if you are trying the root path (/). If you need to render this component at a subpath (e.g. /foo/bar/login), that should be defined as the route path.
<Route path="/foo/bar/login" exact={true} component = {AdminLogin} />
Related
I'm trying to redirect my HomePage Component to a different component with one click of a button. However, when the link is clicked it's changing the path in the browser URL but I'm not able to see any change (i.e., my new Addbook component is not being rendered inside Route).
App.js
import React, { Component, useState } from "react";
import axios from "axios";
import "./styles.css";
import HomePage from "./HomePage.js";
import Addbook from "./AddBook.js";
import {Router,Switch,Route, BrowserRouter} from "react-router-dom";
class App extends React.Component {
render()
{
return (
<BrowserRouter>
<Switch>
<Route exact path="/"><HomePage></HomePage></Route>
<Route path="/add"><Addbook></Addbook></Route>
</Switch>
</BrowserRouter>
);
}
}
export default App;
HomePage.js
import React from "react";
import {BrowserRouter, Link, Router, Switch, useHistory } from "react-router-dom";
class HomePage extends React.Component {
render() {
return ( <div>
<h1>Book Library</h1>
<BrowserRouter>
<Switch>
<Link to="/add"><button id="addbook">Add Book</button></Link>
<Link to="/search"><button id="searchbook">Search Book</button></Link>
</Switch>
</BrowserRouter>
</div>
)
}
}
export default HomePage
AddBook.js
import React from "react";
import axios from "axios";
const addBook = () => {
axios.post("http://localhost:3000/addbook",{
name: this.state.name,
author : this.state.author,
date: this.state.date,
category: this.state.category
}).then(response => response.data).then(data => {
console.log(data);
if(data=="added")
{
}
}, (error) => {
console.log(error);
});
}
class Addbook extends React.Component{
render(){
return (<div>
New Book<input type="text" onChange={(e)=>{
this.setState({name: e.target.value})
}} name="name" id="newbook"/>
Author<input type="text" onChange={(e)=>{
this.setState({author: e.target.value})
}} name="author" id="Author"/>
Date of Publish<input type="date" onChange={(e)=>{
this.setState({date: e.target.value})
}} name="date" id="dtofpub"/>
Category<input type="text" onChange={(e)=>{
this.setState({category: e.target.value})
}} name="category" id="category"/>
<button id="add" onClick={addBook}>ADD</button>
</div> )
}
}
export default Addbook;
you should update homePage like this :
import React from "react";
import {BrowserRouter, Link, Router, Switch, useHistory } from "react-router-dom";
class HomePage extends React.Component {
render() {
return (
<div>
<h1>Book Library</h1>
<Link to="/add"><button id="addbook">Add Book</button></Link>
<Link to="/search"><button id="searchbook">Search Book</button></Link>
</div>
)
}
}
export default HomePage
There is syntax error please replace
<Route exact path="/"><HomePage></HomePage></Route>
To
<Route exact path="/" component={HomePage}></Route>
Apologies if it sounds stupid question. I'm trying to redirect user to the content pages of the app when they are signed in. My current implementation correctly changes the URL in the address bar but doesn't render a component and shows a blank page. Is there something i'm missing in here. Could you please suggest what am i'm missing ?
I tried googling it but couldn't make it work. Here are some of the links i tried.
1- https://tylermcginnis.com/react-router-programmatically-navigate/
2- https://learnwithparam.com/blog/redirect-route-in-react-router/
3- Programmatically navigate using react router
Login Component
class Login extends React.Component {
handleSubmit(e) {
e.preventDefault();
var value = true;
localStorage.setItem('userLoggedIn', JSON.stringify(value));
this.setState({
toUsers: true
})
//this.props.history.push('/users')
}
render() {
if (this.state.toUsers === true) {
return <Redirect to="/users" />
}
return (
<div className="Login">
<form onSubmit={this.handleSubmit}>
Email
<input
type="text"
value={this.state.email}
onChange={this.handleEmailChange}
/>
Password
<input
type="text"
value={this.state.password}
onChange={this.handlePasswordChange}
/>
<button>
Login
</button>
</form>
</div>
);
}
}
export default Login;
App component:
import React, { Component } from 'react';
import { BrowserRouter, HashRouter, Switch, Route } from 'react-router-dom';
import Navigation from './common/Navigation';
import Users from './users/Users.jsx';
import Roles from './roles/Roles.jsx';
import ProtectedRoute from './authentication/ProtectedRoute.jsx';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return <Navigation>
<Switch>
<Route exact path="/users" component={Users} />
<Route exact path="/roles" component={Roles} />
<Route render={() => <div>Not Found</div>} />
</Switch>
</Navigation>
}
}
Component which decides if login page should be displayed or the content pages of the application
export default class AppAuthenticated extends React.Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
toUsers: false,
isUserLoggedIn: false
};
}
componentDidMount() {
const isUserLoggedIn = JSON.parse(localStorage.getItem('userLoggedIn'));
this.setState({
isUserLoggedIn: isUserLoggedIn
});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login />
)}
</>
);
}
}
Main App Component which renders the app
import React from 'react'
import ReactDOM from "react-dom";
import App from './pages/App'
import { BrowserRouter, HashRouter, Switch, Route } from 'react-router-dom';
import PropTypes from "prop-types";
import { withRouter } from "react-router";
import Login from './pages/authentication/Login.jsx';
import AppAuthenticated from './pages/authentication/AppAuthenticated.jsx';
ReactDOM.render(
<HashRouter>
<AppAuthenticated />
</HashRouter>,
document.getElementById("root")
);
Expected Behavior: When user is signed in successfully, they should be redirected to the "App" component where I've defined all the routes that logged in user can access
In your app.js, pass a prop to your login component that can change the container state to render your content pages.
setLoggedIn = ()=>{
this.setState({isUserLoggedIn: true});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login loginSuccess={this.setLoggedIn} />
)}
</>
);
}
Then in your Login Component...
handleSubmit(e) {
e.preventDefault();
var value = true;
localStorage.setItem('userLoggedIn', JSON.stringify(value));
this.setState({
toUsers: true
})
this.props.loginSuccess();
//this.props.history.push('/users')
}
setLoggedIn = ()=>{
this.setState({isUserLoggedIn: true});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login loginSuccess={this.setLoggedIn} />
)}
</>
);
}
this is missing in your passing props #maddy
I'm trying to build a project with Laravel and ReactJs. I have rendered a table and data has been shown. But when I try to use Router in ReactJs to build a CRUD project, it has an error. Could someone help me, please. Here my code, thank you:
My homepage: Example.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import { Link } from "react-router-dom";
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {posts: []};
}
componentWillMount(){
axios.get('http://127.0.0.1:8000/posts')
.then(response => {
this.setState({ posts: response.data });
})
.catch(function (error) {
console.log(error);
})
}
postRow(p){
return (
<tr key = {p.id}>
<td>{p.title}</td>
<td>{p.description}</td>
<td><a>Edit</a></td>
<td><a>Delete</a></td>
</tr>
)
}
render() {
const posts = this.state.posts.map(post => this.postRow(post));
return (
<div>
<table border="1">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{ posts }
</tbody>
</table>
<Link to="/add-post">Add</Link>
//<Route exact path='/add-post' component={CreatePost}/>
</div>
);
}
}
if (document.getElementById('homepage')) {
ReactDOM.render(
<Example />
, document.getElementById('homepage')
);
}
RoutePath.js
import React, {Component} from 'react';
import { Route, BrowserRouter } from "react-router-dom";
import CreatePost from './CreatePost';
import Example from './Example';
export default class RoutePath extends Component{
render(){
return(
<BrowserRouter>
<div>
<Route exact path='/' component={Example}/>
<Route exact path='/add-post' component={CreatePost}/>
</div>
</BrowserRouter>
)
}
}
CreatePost.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
class CreatePost extends Component{
constructor(props){
super(props);
this.state = {postTitle: '', postDescription: ''};
this.titleChange = this.titleChange.bind(this);
this.descriptionChange = this.descriptionChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e){
e.preventDefault();
const post = {
title: this.state.postTitle,
description: this.state.postDescription
}
let uri = 'http://127.0.0.1:8000/api/add';
axios.post(uri,post).then((response) => {
//browserHistory.push('/');
});
}
titleChange(e){
this.setState({
postTitle: e.target.value
})
}
descriptionChange(e){
this.setState({
postDescription: e.target.value
})
}
render(){
return(
<div>
<form onSubmit={this.handleSubmit} method="POST">
<label>Title: </label>
<input type="text" onChange={this.titleChange}/>
<br/>
<label>Description: </label>
<textarea onChange={this.descriptionChange}></textarea>
<br/>
<input type="submit" value="add"/>
</form>
</div>
)
}
}
export default CreatePost;
PostController.php
class PostController extends Controller
{
public function index(){
$post = Post::all();
return response()->json($post);
}
public function store(Request $request){
$post = new Post();
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return response()->json('Post Added');
}
}
In the routePath:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Switch, Route, BrowserRouter } from 'react-router-dom'; // import BrwoserRouter here
import CreatePost from './CreatePost';
import Example from './Example';
export default class RoutePath extends Component {
render() {
return (
<BrowserRouter> // use it here...
<Switch>
<Route exact path="/" component={Example} />
<Route exact path="/add-post" component={CreatePost} />
</Switch>
</BrowserRouter>
);
}
}
If you look in RoutePath.js you'll see that you've got your two routes within another route. You need to change this to BrowserRouter. See the docs, https://reacttraining.com/react-router/web/api/Route
This should fix your issue.
<Route>
<div>
<Switch>
<Route exact path='/' component={Example}/>
<Route exact path='/add-post' component={CreatePost}/>
</Switch>
</div>
</Route>
I'm creating a router in App.js file.
I'm creating a login page and I change page with this.props.history.push('/homepage') to go to the homepage. It works.
Now I'm in /homepage and i would like to do the same but it don't works ...
I make: this.context.history.push('/test'); and I've got an error "TypeError: Cannot read property 'push' of undefined".
I already tried to use "this.context.router.history.push('/page');" but i have the same error. I tried to use browserHistory instead of HashRouter but it don't works.
The only thing who work is to create functions and to call them with the buttonclick. But i can't do it with the react way !
Include App.js:
import React, {Component} from 'react';
import {HashRouter as Router, Route} from 'react-router-dom';
import HomePage from './dashboard/Dashboard';
import Register from "./login/Register"
import Login from "./login/Login"
import Admin from "./admin/Admin"
class App extends Component {
render() {
return (
<Router basename="/">
<div>
<Route exact path="/" component={Login}>
</Route>
<Route exact path="/homepage" component={HomePage}>
</Route>
<Route exact path="/register" component={Register}>
</Route>
<Route exact path="/login" component={Login}>
</Route>
<Route exact path="/admin" component={Admin}>
</Route>
</div>
</Router>
);
}
}
export default App;
Include Login file
import React, {Component} from 'react';
import {Link, NavLink} from 'react-router-dom';
import O2Connexion from './O2Connexion'
import "../App.css"
import Axios from 'axios'
import AreaLogo from '../ressources/arealogo.png'
class Login extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
test: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
let target = e.target;
let value = target.type === 'checkbox' ? target.checked : target.value;
let name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(e) {
e.preventDefault();
this.props.history.push('/homepage')
}
}
render() {
...
Include NavBar file
import React, { Component } from 'react';
import { Layout, Header, Navigation, Content } from 'react-mdl';
import {HashRouter as Router, Route, Link} from 'react-router-dom';
class Navbar extends Component {
constructor(props) {
super(props);
this.test = this.test.bind(this);
}
test(e) {
e.preventDefault();
//ne marche pas comme ça
this.context.history.push('/homepage');
}
render() {
return (
<div style={{height: '300px', position: 'relative'}}>
<Layout fixedHeader>
<Header title={<span><span style={{ color: '#ddd' }}>Area</span></span>}>
<Navigation>
<a onClick={this.test}>Home Page</a>
<a>Admin</a>
<a>Log out</a>
</Navigation>
</Header>
<Content />
</Layout>
</div>
);
}
}
export default Navbar;
So it don't works on the navabar file and i have no idea why
Can someone explain me why it don't works and if it exist a "reactjs" way to do it ? Thank you and have a nice evenning
You have to wrap your components with withRouter hoc like:
import React, { Component } from 'react';
import { withRouter } from 'react-router';
class Navbar extends Component { ... }
const NavbarWithRouter = withRouter(Navbar);
export default NavbarWithRouter;
Doing this way you could access match, location, history inside Navbar's component props
You need to repeat steps above for each component where you need access for seeking properties
container.js -
//Here we render the recipe details and display add recipe form.
import React, { Component } from 'react';
import './App.css';
import AddRecipe from './addrecipe.js';
class App extends Component {
constructor(props){
super(props);
this.state={ recipes :[] }
this.addRecipe=this.addRecipe.bind(this);
}
addRecipe (recipe) {
this.setState({
recipes: [...this.state.recipes, recipe]
});
}
componentWillMount(){
this.setState({
recipes : require('./sample-recipes')
});
}
home(e){
window.location='/a';
}
render() {
return (
<div className="App">
<h2>Welcome to the Recipe Book</h2>
<dl>
{this.state.recipes.map(recipe => {
return ( <div key={recipe.name} onClick={this.home}>
<dt>{recipe.name}</dt>
<dd>{recipe.ingredient}</dd>
<div><img src='{recipe.image}' className="image"/></div>
<hr></hr>
</div>
)
})
}
</dl>
<button className="addButton" onClick={() =>
{this.setState({ display: !this.state.display })}}>
Add Recipe
</button>
<AddRecipe addRecipe={this.addRecipe}
display={this.state.display} />
</div>
);
}
}
export default App;
In home function it directs the page to ('/recipe') that is the file store.js
import React, { Component } from 'react';
import AddRecipe from './addrecipe.js';
var StorePicker = React.createClass({
render : function() {
return (
<form className="store-selector">
<h2>{recipe.name}</h2> --->//gives error recipe is not defined.
</form>
)
}
});
export default StorePicker;
How do I display recipe.name,ingredients,image in the new page given by ('/recipe').There is another file addrecipe.js that creates a form to take the input from user.
This is my index.js file--
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import AddRecipe from './addrecipe';
import StorePicker from './store';
import App from './container'
var ReactRouter = require('react-router');
var Router = ReactRouter.Router;
var Route = ReactRouter.Route;
var Navigation = ReactRouter.Navigation;
import createHistory from 'history/createBrowserHistory'
var routes = (
<Router history={createHistory()}>
<switch>
<Route exact={true} path="/recipe" component={StorePicker} />
<Route exact={true} path="/" component={App}/>
</switch>
</Router>
);
ReactDOM.render(routes, document.getElementById('root'));