React-Router Link Button not with Router? - javascript

I have a very simple react app.
In the main App.js I have a Routerwith my routes.
In another separate component, PostItem, which lives in MainComponent, I have a Link button to another component, JobPost.
I keep getting:
Cannot GET /job/7
Does this set up work? Or do I need to have a Router element in my component with my Link?
App.js:
import React from 'react';
import { render } from 'react-dom';
import MainComponent from './index.js';
import JobPost from './components/JobPost.js';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const App = () => (
<Router>
<div>
<Route path="/" exact component={MainComponent} />
<Route path="/job/:id" exact component={JobPost} />
</div>
</Router>
);
render(<App />, document.getElementById('root'));
PostItem.js:
import React from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default function PostItem(props){
return(
<div className="post-item">
<div className="job-details">
<h2 className="job-title" dangerouslySetInnerHTML={{__html: props.title }} />
<h3 className="job-location"> Test Company - <i>Test Location</i></h3>
<div className="job-description">
<span dangerouslySetInnerHTML={{__html: props.content }} />
</div>
</div>
<button className="view-btn">
<Link to={ `/job/` + props.id } >
View
</Link>
</button>
</div>
);
}
JobPost.js:
import React, { Component } from 'react';
//make actual class and render again
export default class JobPost extends Component{
constructor(props){
super(props);
this.state={
id: this.props.match.params.id
};
}
componentDidMount(){
//fetch id from component
console.log(this.state.id);
}
render(){
return(
<div className="post-container">
<div className="job-details">
<h2 className="job-title" dangerouslySetInnerHTML={{__html: props.title }} />
<h3 className="job-location"> Test Company - <i>Test Location</i></h3>
<div className="job-description">
<span dangerouslySetInnerHTML={{__html: props.content }} />
</div>
</div>
<button className="apply-btn">Apply</button>
</div>
);
}
}

Related

routes not render the content of Register component and Login component

i did routes of my social chat app with react v6, so the app component display their content but the other ones(Register component and Login component) didn't show me its own content, i have no idea how to fix this problem. this is my code:
enter code here
import './App.css';
import Navbar from './components/layout/Navbar';
import Footer from './components/layout/Footer';
import Landing from './components/layout/Landing';
import {BrowserRouter as Router, Routes, Route} from "react-router-dom";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
import MatchPath from "./utils";
import React from 'react';
function App() {
return (
<Router >
<div className="App">
<Navbar />
<Routes>
<Route path="" element={<Landing />} />
<Route path="" element={
<div className="container">
<Route path="register" element={< Register/>} />
<Route path="login" element={< Login/>} />
</div>
} ></Route>
</Routes>
<Footer />
</div>
</Router>
);
}
export default App;
import React, { Component } from 'react';
class Register extends Component {
render() {
return (
Register
</div>
)
}
}
export default Register;
import React, { Component } from 'react'
class Login extends Component {
render() {
return (
Login
LoginLoginLoginLogin
)
}
}
export default Login;
import React, { Component } from 'react';
import { Link } from "react-router-dom";
class Navbar extends Component {
render() {
return (
DevConnector
<div className ="collapse navbar-collapse" id="mobile-nav">
<ul className ="navbar-nav mr-auto">
<li className ="nav-item">
<Link className ="nav-link" to="/profiles"> Developers
</Link>
</li>
</ul>
<ul className ="navbar-nav ml-auto">
<li className ="nav-item">
<Link className ="nav-link" to="register">Sign Up</Link>
</li>
<li className ="nav-item">
<Link className ="nav-link" to="login">Login</Link>
</li>
</ul>
</div>
</div>
</nav>
)
}
}
export default Navbar;

'match.params.id' is missing in props validation

For this project, I am following a tutorial. I am a beginner.
My code is throwing an error at
console.log(props.match.params.id);
This is the error
'match.params.id' is missing in props validation
If I change it to console.log(props), it prints {}, which is empty?
What I want it to do is print the id of the product page, in this case it would be 2. "http://localhost:3000/product/2" How can I get this to work?
Here is my full ProductScreen.js
import React from 'react';
function ProductScreen(props) {
console.log(props.match.params.id);
return <div>ProductScreen</div>
}
export default ProductScreen;
And here is app.js with my HTML in it
import React from 'react';
import {BrowserRouter, Routes, Route, Link} from 'react-router-dom';
import './App.css';
import HomeScreen from './Screens/HomeScreen';
import ProductScreen from './Screens/ProductScreen';
function App() {
const openMenu = () =>{
document.querySelector(".sidebar").classList.add("open");
}
const closeMenu = () =>{
document.querySelector(".sidebar").classList.remove("open");
}
return (
<BrowserRouter>
<div className="grid-container">
<header className="header">
<div className="brand">
<button onClick={openMenu}>
☰
</button>
<Link to="/" >E-Commerce</Link>
</div>
<div className="header-links">
Sign In
Cart
</div>
</header>
<aside className="sidebar">
<h3>Shopping Categories</h3>
<button className="sidebar-close-button" onClick={closeMenu}>x</button>
<ul>
<li>
Pants
</li>
<li>
Shirts
</li>
</ul>
</aside>
<main className="main">
<div className="content">
<Routes>
<Route exact path="/" element={<HomeScreen />} />
<Route path="/product/:id" element={<ProductScreen/>} />
</Routes>
</div>
</main>
<footer className="footer">
All rights reserved.
</footer>
</div>
</BrowserRouter>
);
}
export default App;
I'm sorry if that's too much or too little information, this is my first post here.
You aren't passing any props to the ProductScreen component, do this instead
import React from 'react';
import { useParams } from "react-router-dom";
function ProductScreen(props) {
// console.log(props.match.params.id);
const { id } = useParams();
console.log(id);
return <div>ProductScreen</div>
}
export default ProductScreen;

Passing State of App.js to Child Component

I'm working on the main page of a website and I'd like to have a specific nav/menu bar for the main page and a different one for the other components (the main page hides de "home" button and the others show it).
The issue I have at the moment is that the logic of rendering this menu lives on App and I'm having a hard time to find the proper way to pass the state of my App component to the other components, probably just because of the lack of experience.
import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
import Main from "./main";
import MapContainer from "./mapcontainer";
import Venue from "./venue";
import Schedule from "./schedule";
import Accommodation from "./accommodation";
import Couple from "./couple";
import Honeymoon from "./honeymoon";
import Uploader from "./uploader";
import Friday from "./friday";
import Saturday from "./saturday"
import Sunday from "./sunday";
import Dresscode from "./dresscode";
export class App extends React.Component {
constructor(props) {
super(props);
this.state = {
error: false,
isHome: true
};
}
componentDidMount() {
console.log("App mounted");
}
render() {
function HomeComponentMenu(props) {
return (
<nav className="header-on-app">
<button>Contact Us</button>
<button className="logout-btn">Logout</button>
</nav>
);
}
function AllOtherComponentsMenu(props) {
return (
<nav className="header-on-app">
<button><Link to="/">Home</Link></button>
<button>Contact Us</button>
<button className="logout-btn">Logout</button>
</nav>
);
}
const isHome = this.state.isHome;
let menu;
if (isHome) {
menu = <HomeComponentMenu/>;
} else {
menu = <AllOtherComponentsMenu/>;
}
return (
<BrowserRouter>
<nav className="header-on-app">{menu}</nav>
<div className="app-container">
<Route exact path="/" component={Main} />
<Route exact path="/venue" component={Venue}/>
<Route exact path="/venuemap" component={MapContainer}/>
<Route exact path="/schedule" component={Schedule}/>
<Route exact path="/accommodation" component={Accommodation}/>
<Route exact path="/couple" component={Couple}/>
<Route exact path="/honeymoon" component={Honeymoon}/>
<Route exact path="/uploader" component={Uploader} />
<Route exact path="/friday" component={Friday} />
<Route exact path="/saturday" component={Saturday} />
<Route exact path="/sunday" component={Sunday} />
<Route exact path="/dresscode" component={Dresscode} />
</div>
</BrowserRouter>
);
}
}
Component I'd like to set isHome to false
import MapContainer from "./mapcontainer";
export default class Venue extends React.Component {
constructor(props){
super(props);
this.state = {
error:false,
}
}
render() {
return (
<div className="venue-container">
<h1>Anna & Rodolfo</h1>
<h2><span>_______</span> Venue . Local . Veranstalungsort <span>_______</span></h2>
{this.state.error && <h2 className="error">Ops! Something went wrong.</h2>}
<div className="grid-container-venue">
<div className="item">
<img src="venue.png" alt="Avatar" className="image"/>
<div className="background-grid-items">
<div className="text-address">
<a href="https://www.g71972,15z/data=!4887b!8m2!3d52.47094!4d12.71972">
<p>Kulturschloss</p>
<p>Abcd.30 3456 Berlin </p>
<p>Germany . Alemanha . Deutschland</p>
</a>
</div>
</div>
</div>
<div className="item">
<img src="website.png" alt="Avatar" className="image"/>
<div className="background-grid-items">
<div className="text">
<a href="https://www.kult.de/">
<p>To the Website</p>
<p>Para o Website</p>
<p>Zur Website</p>
</a>
</div>
</div>
</div>
<div className="item">
<img src="transportation.png" alt="Avatar" className="image"/>
<div className="background-grid-items">
<div className="text">
<p>Transportation</p>
<p>Traslado</p>
<p>Transport</p>
</div>
</div>
</div>
<div className="item">
<div className="background-grid-venue">
<div className="map">
<MapContainer/>
</div>
</div>
</div>
</div>
</div>
);
}
}
Since my components are being rendered by React Router, I tried to render props passing it in an inline function and afterwards pass along to the argument I was creating, but somehow it didn't work. Would you have any suggestions on how to solve this? Thank you very much!
To pass a state to a child component, you have to pass it as props of the child component.
e.g.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import TableView from './TableView'
export default class App extends Component {
state = {
item: 'this is the item'
}
render() {
return(
<Router>
<Route exact path="/home">
<TableView itemList={this.state.item}></TableView>
</Route>
</Router>
)
}
}
to get the props in the child component
import React, { Component } from 'react'
export default class TableView extends Component {
render(){
<React.Fragment>
{this.props.item}
</React.Fragment>
}
}
Hope it helps
EDIT:
It would also help to debug if you have the react devtools addons in your browser to check if the values of the state of each component
To pass props to a react route you have to define it in the render function like this:
<Route exact path="/venue" render={(props) => <Venue updateHomeState={this.updateHomeState}/>}/>
To alter the isHome state on the parent, you could define that function on the parent like:
updateHomeState = (newState) => {
this.setState({ isHome: newState })
}
And then call it in componentDidMount() of your child component like this.props.updateHomeState(newState).

React-router-dom rendering component on the same page

i am using react-router-dom in my project when i am proving routes instead of rendering the component in another page dom rendering component in the same page below my first component
My App.js
import React,{Component} from 'react';
import './App.css'
import Layout from './components/front/layout'
import FirstPage from './components/index/firstpage';
import {BrowserRouter ,Switch,Route} from 'react-router-dom';
class App extends Component {
render(){
return (
<div className="container">
<BrowserRouter>
<FirstPage/>
<Switch>
<Route path='/Layout' exact component={Layout} />
</Switch>
</BrowserRouter>
</div>
);
}
}
export default App;
My another middlePortion.js where i am using imported from react-router-dom to route to another page
import React from 'react';
import { Button, Form } from 'reactstrap';
import axios from 'axios';
import '../../css/style.css'
import {Link} from 'react-router-dom'
class Middleportion extends React.Component {
constructor(props){
super(props);
this.Submit = this.Submit.bind(this);
}
render() {
const layStyle={
color:'white'
};
return (
<div className='row frnt'>
<div className="col-md-3">
</div>
<div className="col-md-6 am ">
<div className="row align-items-center">
<div className="row justify-content-center bg-primary pp">
<ul className="list-unstyled">
<li><Link style={layStyle} to='/Layout'>
male
</Link></li>
</ul>
</div>
</div>
</div>
<div className="col-md-3">
</div>
</div>
);
}
}
export default Middleportion;
I want to render my Layout component on separate page but its rendering on the same page please help me out
The problem with your code is that you're rendering FirstPage manually as if to be hard coded.
In order to get FirstPage and Layout to render in separate routes, you need to create a separate route inside your <Switch> and use FirstPage as the component prop like you did with Layout.
It would look like this:
(
<div className="container">
<BrowserRouter>
<Switch>
<Route exact path='/' component={FirstPage} />
<Route exact path='/Layout' component={Layout} />
</Switch>
</BrowserRouter>
</div>
)
With the setup above, the FirstPage component would render only on the / route and the Layout component would only render on the /layout route.

Create-React-App: router is marked as required in Link

I've got a problem with Link in react router in one component. Once I try to use Link, the console shows this error: Failed context type: The context router is marked as required in Link, but its value is undefined. I've seen all similar threads about this problem here, but there's no solution to this exact issue. I'm using all the latest versions of all frameworks and componets (just downloaded everything a couple of days ago), so it's definitely not about upgrading anything.
The structure is like this:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { BrowserRouter as Router, Route} from 'react-router-dom';
import { Link } from 'react-router-dom';
import About from './components/About';
import Posting from './components/Posting';
import Groups from './components/Groups';
ReactDOM.render(<App />, document.getElementById('app'));
ReactDOM.render(
<Router>
<div>
<Route exact path='/' component={About} />
<Route path='/post' component={Posting} />
<Route path='/groups' component={Groups} />
</div>
</Router>,
document.getElementById('content')
);
registerServiceWorker();
App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route} from 'react-router-dom';
import { Link } from 'react-router-dom';
import SideMenuUserInfo from './components/sidemenu/SideMenuUserInfo';
import SideMenu from './components/sidemenu/SideMenu';
import SideMenuFooter from "./components/sidemenu/SideMenuFooter";
import TopNav from "./components/topnav/TopNav";
class App extends Component {
render() {
return(
<div className="main_container">
<div className="col-md-3 left_col">
<div className="left_col scroll-view">
<div className="navbar nav_title" style={{border: 0}}>
<i className="fa fa-paw"></i> <span>Logo here</span>
</div>
<div className="clearfix"></div>
<SideMenuUserInfo />
<br />
<SideMenu />
<SideMenuFooter />
</div>
</div>
<TopNav />
<div id="content" className="right_col" role="main">
</div>
<footer>
<div className="pull-right">
Footer text here
</div>
<div className="clearfix"></div>
</footer>
</div>
);
}
}
export default App;
SideMenuUnfoldLink.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class SideMenuUnfoldLink extends Component {
render() {
return(
<li>
<a>
<i className={this.props.faClass}></i>{this.props.text}<span className="fa fa-chevron-down"></span>
</a>
<ul className="nav child_menu">
<li><Link to="/">Home</Link></li> <<<<-- THE PROBLEM IS HERE
</ul>
</li>
);
};
}
export default SideMenuUnfoldLink;
And About.js (as a working example of Link)
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class About extends Component {
render() {
return (
<div>
<h2>Это About</h2>
<ul>
<li><Link to="/groups">Groups</Link></li>
<li><Link to="/">Main</Link></li>
</ul>
</div>
);
}
}
export default About;
The Link works with the About component like a charm. The error starts to pop up once I use Link in my SideMenuUnfoldLink component.
I suppose the Router is just not initialized by the moment SideMenuUnfoldLink wants to use Link. But how can I go about it?
I've just found the solution. It is to wrap the router around the entire
application to make it available to all components like this:
render() {
return(
<Router>
<div className="main_container">
<div className="col-md-3 left_col">
<div className="left_col scroll-view">
<div className="navbar nav_title" style={{border: 0}}>
<i className="fa fa-paw"></i> <span>Logo here</span>
</div>
<div className="clearfix"></div>
<SideMenuUserInfo />
<br />
<SideMenu />
<SideMenuFooter />
</div>
</div>
<TopNav />
<div id="content" className="right_col" role="main">
</div>
<footer>
<div className="pull-right">
Footer text here
</div>
<div className="clearfix"></div>
</footer>
</div>
</Router>
);
}
And of course removing this part:
ReactDOM.render(
<Router>
<div>
<Route exact path='/' component={About} />
<Route path='/post' component={Posting} />
<Route path='/groups' component={Groups} />
</div>
</Router>,
document.getElementById('content')
);
Here's a more detailed explanation https://reacttraining.com/react-router/
Lots of thanks to the author of that video :)

Categories

Resources