Adding para "id" in react.js url - mysql

I wanted to add my currentUser.id at the back of http://localhost:8081/profileand look something like this http://localhost:8081/profile/1. I am using node.js and MySQL as the backend database. But I cannot seem it get it to work by using router "/profile/:id". I am able to display database information in the profile but did not manage to add id into the URL link. what I am doing wrong?
import React from 'react';
import "./App.css"
import Navbar from './components/Navbar';
import { Switch, Route} from 'react-router';
import { BrowserRouter } from 'react-router-dom'
import Home from './components/pages/HomePage/Home'
import Footer from './components/pages/Footer/Footer';
import Service from './components/Service';
import Info from './components/pages/Info/Info';
import infoMs from './components/pages/Info/infoMs';
import DVC from './components/pages/Info/DVC';
import ike from './components/pages/Info/ike';
import Login from './components/Login';
import Register from './components/Register';
import Profile from './components/Profile';
import About from './components/aboutUs/about';
import facilities from './components/facilities';
import research from './components/research';
import computing from './components/computing';
import alumni from './components/Alumni';
import compstu from './components/studys/compstu';
import useng from './components/studys/useng';
import master from './components/studys/master';
import DnM from './components/DnM';
function App()
{
return(
<BrowserRouter>
<Navbar />
<Switch>
<Route exact path={["/", "/home"]} component={Home}/>
<Route path='/service' component={Service}/>
<Route path='/phua' component={Info}/>
<Route path='/foong' component={infoMs}/>
<Route exact path='/login' component={Login}/>
<Route exact path="/register" component={Register} />
<Route path="/profile" component={Profile} />
<Route exact path="/about" component={About} />
<Route exact path="/fac" component={facilities} />
<Route exact path="/research" component={research} />
<Route exact path="/computing" component={computing} />
<Route exact path="/alumni" component={alumni} />
<Route exact path="/compstu" component={compstu} />
<Route exact path="/useng" component={useng} />
<Route exact path="/master" component={master} />
<Route path="/dvc" component={DVC} />
<Route path="/ike" component={ike} />
<Route path="/DnM" component={DnM} />
</Switch>
<Footer />
</BrowserRouter>
);
}
export default App;
this is my navbar
import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { FaBars, FaTimes } from 'react-icons/fa'
import { Button } from './Button'
import './Navbar.css'
import { IconContext } from 'react-icons/lib'
import AuthService from "../services/auth-service";
import Dropdown from './Dropdown';
import {
BsFillCaretDownFill,
} from 'react-icons/bs';
export const img1 = require('./images/kdu.png');
function Navbar() {
const [currentUser, setCurrentUser] = useState(undefined);
useEffect(() => {
const user = AuthService.getCurrentUser();
if (user) {
setCurrentUser(user);
}
}, []);
const logOut = () => {
AuthService.logout();
setCurrentUser(undefined);
};
const [click, setClick] = useState(false);
const [button, setButton] = useState(true);
const [dropdown, setDropdown] = useState(false);
const handleClick = () => setClick(!click);
const closeMobileMenu = () => setClick(false)
const showButton = () => {
if (window.innerWidth <= 960) {
setButton(false)
} else {
setButton(true)
}
};
useEffect(() => {
showButton();
}, []);
const onMouseEnter = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(true);
}
};
const onMouseLeave = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(false);
}
};
window.addEventListener('resize', showButton);
return (
<>
<IconContext.Provider value={{ color: "#fff" }}>
<nav className='navbar'>
<div className='navbar-container container'>
<Link to='/' className='navbar-logo' onClick={closeMobileMenu}>
<img src="/images/Logo-WHITE.png"
alt="UOWKDU Logo" width="35%" height="85%" className='navbar-icon' />
</Link>
<div className='menu-icon' onClick={handleClick}>
{click ? <FaTimes /> : <FaBars />}
</div>
<ul className={click ? 'nav-menu active' : 'nav-menu'}>
<li className='nav-item'>
<Link to='/' className='nav-links' onClick={closeMobileMenu}>
Home
</Link>
</li>
<li className='nav-item'>
<Link to='/computing' className='nav-links' onClick={closeMobileMenu}>
Study
</Link>
</li>
<li className='nav-item' >
<Link
to='/service'
className='nav-links'
onClick={closeMobileMenu}
>
Staff
</Link>
</li>
<li className='nav-item' onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<Link
className='nav-links'
onClick={closeMobileMenu}
>
About Us <BsFillCaretDownFill />
</Link>
{dropdown && <Dropdown />}
</li>
{currentUser ? (
<li className='nav-btn'>
<Link to='/login' className='btn-link' onClick={logOut}>
<Button buttonStyle='btn--outline' >LogOut</Button>
</Link>
</li>
) : (
<li className="nav-btn">
<Link to='/login' className='btn-link' >
<Button buttonStyle='btn--outline' >Login</Button>
</Link>
</li>
)}
{currentUser ? (
<li className="nav-btn">
<Link to={'/profile' } className='btn-link' >
<Button buttonStyle='btn--outline' >{currentUser.username}</Button>
</Link>
</li>
) : (
<li className="nav-btn">
<Link to='/register' className='btn-link'>
<Button buttonStyle='btn--outline' >Register</Button>
</Link>
</li>
)}
<Link
className='social-icon-link'
to={
'//www.uowmkdu.edu.my/ug-virtual-tour/'
}
target='_blank'
aria-label='GoogleMapKDU'
><Button buttonStyle='btn--outline'>Tour</Button></Link>
</ul>
</div>
</nav>
</IconContext.Provider>
</>
)
}
export default Navbar

Change
<Link to={'/profile' } className='btn-link' >
to
<Link to={`/profile/${currentUser.id}` } className='btn-link' >

Related

Nesting React routes to login-protected pages [duplicate]

This question already has answers here:
How to create a protected route with react-router-dom?
(5 answers)
Closed 8 months ago.
I am using react-router-dom#6.3.0
I have created a React app where certain Private pages are accessible only users who have logged in.
You can find a demo here, and a GitHub repo here.
A simplified version of this is shown below.
I have wrapped every Private page in its own RequireLogin component, and this works:
<Route
path="/private1"
element={
<RequireLogin redirectTo="/">
<Private
text="Private Page #1"
/>
</RequireLogin >
}
/>
The RequireLogin component redirects to a page with the Login component if the user is not logged in, and renders the requested component only to a logged in user.
My question is this:
Is it there a way to wrap all the Private routes inside one RequireLogin component, or do I have to wrap each one separately?
import React, { createContext, useContext, useState } from 'react'
import ReactDOM from 'react-dom';
import {
BrowserRouter as Router,
Routes,
Route,
Navigate,
NavLink
} from "react-router-dom";
const UserContext = createContext()
const UserProvider = ({children}) => {
const [ loggedIn, logIn ] = useState("")
return (
<UserContext.Provider
value={{
loggedIn,
logIn
}}
>
{children}
</UserContext.Provider>
)
}
function App() {
return (
<Router>
<UserProvider>
<Routes>
<Route
path="/"
element={<NavLink to="/login">Log In</NavLink>}
/>
<Route
path="/login"
element={<Login />}
/>
<Route
path="/private1"
element={
<RequireLogin redirectTo="/login">
<Private
text="Private Page #1"
/>
</RequireLogin >
}
/>
<Route
path="/private2"
element={
<RequireLogin redirectTo="/login">
<Private
text="Private Page #2"
/>
</RequireLogin >
}
/>
</Routes>
</UserProvider>
</Router>
);
}
function Menu({hideLogOut}) {
const { loggedIn } = useContext(UserContext)
if (loggedIn) {
if (!hideLogOut) {
return <ul>
<li><NavLink to="/login">Log Out</NavLink></li>
<li><NavLink to="/private1">Private #1</NavLink></li>
<li><NavLink to="/private2">Private #2</NavLink></li>
</ul>
} else {
return <ul>
<li><NavLink to="/private1">Private #1</NavLink></li>
<li><NavLink to="/private2">Private #2</NavLink></li>
</ul>
}
} else {
return <p>Not Logged In</p>
}
}
function RequireLogin ({ children, redirectTo }) {
const { loggedIn } = useContext(UserContext);
return loggedIn
? children
: <Navigate to={redirectTo} />;
}
function Private({text}) {
return (
<div>
<Menu />
<h1>{text}</h1>
</div>
)
}
function Login() {
const { loggedIn, logIn } = useContext(UserContext)
const toggleLogged = () => {
logIn(!loggedIn)
}
return (<div>
<Menu
hideLogOut={true}
/>
<label htmlFor="loggedIn">
<input
type="checkbox"
name="loggedIn"
id="loggedIn"
checked={loggedIn}
onChange={toggleLogged}
/>
Pretend that we are logged in
</label>
</div>)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
I use a second router for the private routes, wrapped with a single <RequireLogin>. Example:
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegistrationPage />} />
<Route path="*" element={
<RequireLogin>
<Routes>
<Route path="/" element={<FeedPage />} />
<Route path="/explore" element={<ExplorePage />} />
<Route path="/user/:username" element={<UserPage />} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</RequireLogin>
} />
</Routes>

The parameter's value don't display with TS

Goal:
Display the parameter's value in the webpage when you click on the text "DetailView"
Problem:
The value don't display and I am not sure if this tis the correct error for this case.
"The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option.(17016)"
How should I solve it?
Thank you!
Stackblitz:
https://stackblitz.com/edit/react-router-typescript-example-asrnpk?
Other info:
*Newbie in react TS
----------------------------
import * as React from 'react';
import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom';
import { render } from 'react-dom';
import { Home, Foo, Bar } from './Pages';
import DetailView from './DetailView';
import './style.css';
class App extends React.Component {
render() {
return (
<Router>
<div>
<nav>
<Link to="/">Home</Link>
<br />
<Link to="/foo">Foo</Link>
<br />
<Link to="/bar">Bar</Link>
<br />
<Link to="/detailview/3}">DetailView</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/foo" element={<Foo />} />
<Route path="/bar" element={<Bar />} />
<Route path="/detailview/:p1?" element={<DetailView />} />
</Routes>
</div>
</Router>
);
}
}
render(<App />, document.getElementById('root'));
----------------
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
interface MatchParams {
id: string;
}
interface Props extends RouteComponentProps<MatchParams> {
// ...
}
const DetailView: React.FC<Props> = ({ match }: Props): JSX.Element => {
const params = match.params;
return <>{`Test "${params.id}"`}</>;
};
export default DetailView;
-------------------
import React from 'react';
export const Home = () => <h1>Home Page</h1>;
export const Foo = () => <h1>Foo Page</h1>;
export const Bar = () => <h1>Bar Page</h1>;

React Router is showing only one of the Switch components and does nothing when others are called

My routing component looks like this:
import { Link, Route, Switch } from 'react-router-dom';
import Nav from 'react-bootstrap/Nav'
import AllWorkouts from './Workout/AllWorkouts/AllWorkouts';
import WorkoutCreate from './Workout/WorkoutCreate/WorkoutCreate';
import WorkoutDetails from './Workout/WorkoutDetails/WorkoutDetails';
import WorkoutEdit from './Workout/WorkoutEdit/WorkoutEdit';
const Main = () => {
return (
<Switch>
<Route path="/workout/:id/edit" componnet={WorkoutEdit} />
<Route path="/workout/:id/details" componnet={WorkoutDetails} />
<Route path="/workout/create" componnet={WorkoutCreate} />
<Route path="/workout/all" component={AllWorkouts} />
</Switch>
);
}
export default Main;
I have included BrowserRouter in index.js and the only route that is matching is path="/workout/all". I cannot call any of the other routs with Link or directly in the URL.
When I call /workout/all I can see the component with all the other routes nothing happens.
Thank you!
Below is the other component and I do not see any misspelling error:
import { Link, Route, Switch } from 'react-router-dom';
import Button from 'react-bootstrap/Button'
const AllWorkouts = () => {
return (
<div>
<Link to="/workout/create">
<Button variant="outline-primary">Create new workout</Button>{' '}
</Link>
<h1>Hello from AllWorkouts</h1>
</div>
);
}
export default AllWorkouts;
You have misspelled component in the other routes
mport { Link, Route, Switch } from 'react-router-dom';
import Nav from 'react-bootstrap/Nav'
import AllWorkouts from './Workout/AllWorkouts/AllWorkouts';
import WorkoutCreate from './Workout/WorkoutCreate/WorkoutCreate';
import WorkoutDetails from './Workout/WorkoutDetails/WorkoutDetails';
import WorkoutEdit from './Workout/WorkoutEdit/WorkoutEdit';
const Main = () => {
return (
<Switch>
<Route path="/workout/:id/edit" component={WorkoutEdit} />
<Route path="/workout/:id/details" component={WorkoutDetails} />
<Route path="/workout/create" component={WorkoutCreate} />
<Route path="/workout/all" component={AllWorkouts} />
</Switch>
);
}
export default Main;

Unexpected re-rendering of components

I'm trying to navigate back to a Menu component, but when I trigger a route to do so, the previous rendered Practice component is rendered in the root domain level, which should just be for the Menu component.
The solutions for similar questions on StackOverflow say to use exact in the route, but as you can see I have this in place.
How do I make this work as expected? Thanks.
Here's what I have...
App.js
import React from 'react';
import './App.css';
import PracticeContextProvider from './contexts/PracticeContext';
import {BrowserRouter as Router, Route, Switch, Link} from 'react-router-dom';
import Menu from './pages/Menu';
function App() {
return (
<div className="app">
<PracticeContextProvider>
<Menu />
</PracticeContextProvider>
</div>
);
}
export default App;
Menu.js
import React, { useContext } from 'react';
import {BrowserRouter as Router, Route, Switch, Link, useParams, useLocation, useRouteMatch} from 'react-router-dom';
import { PracticeContext } from '../contexts/PracticeContext';
import Practice from './Practice';
import ModuleLanguageSelector from '../components/ModuleLanguageSelector';
import ModuleListMenuItem from '../components/ModuleListMenuItem';
const Menu = () => {
const { modulesJson } = useContext(PracticeContext);
return (
<div>
<h1>Menu</h1>
<Router>
<Switch>
<Route exact path="/">
<ModuleLanguageSelector />
{ modulesJson && (
modulesJson.map(module => {
return (
<Link to={'/Practice/' + module._id} key={ module._id }>
<ModuleListMenuItem module={ module }></ModuleListMenuItem>
</Link>
)
})
)}
</Route>
<Route exact path="/Practice/:moduleId" component={Practice} />
</Switch>
</Router>
</div>
);
}
export default Menu;
Practice.js
import React, { useContext } from 'react';
import {BrowserRouter as Router, Route, Switch, Link, useParams, useLocation, useRouteMatch} from 'react-router-dom';
import { PracticeContext } from '../contexts/PracticeContext';
import Menu from './Menu';
import ModulePracticeAnswerArea from '../components/ModulePracticeAnswerArea';
import ModulePracticeQuestion from '../components/ModulePracticeQuestion';
import ModulePracticeProgress from '../components/ModulePracticeProgress';
import ModulePracticeTutorial from '../components/ModulePracticeTutorial';
const Practice = () => {
const { moduleId } = useParams();
const { questionIndex } = useContext(PracticeContext);
return (
<Router>
<div className="module-practice-screen">
<h1>Practice</h1>
<div className="module-practice-container">
<Link to={'/'}>
<button className="quit-practice">X</button>
</Link>
{
moduleId ?
<React.Fragment>
{/*<ModulePracticeTutorial moduleId={ moduleId } />*/}
<ModulePracticeProgress questionNumber={ questionIndex } />
<ModulePracticeQuestion moduleId={ moduleId } questionNumber={ questionIndex } />
<ModulePracticeAnswerArea moduleId={ moduleId } questionNumber={ questionIndex } />
</React.Fragment>
:
<h3>The menu should appear here!</h3>
}
</div>
</div>
<Switch>
<Route exact path="/" component={Menu} />
</Switch>
</Router>
);
};
export default Practice;
You don't need <Router> and <Switch> in Practice
const Practice = props => {
const { moduleId } = useParams();
const { questionIndex } = useContext(PracticeContext);
return (
<div>
<div className="module-practice-screen">
<h1>Practice</h1>
<div className="module-practice-container">
<Link to="/">
<button>X</button>
</Link>
{moduleId ? (
<React.Fragment>
{/*<ModulePracticeTutorial moduleId={ moduleId } />*/}
<ModulePracticeProgress questionNumber={questionIndex} />
<ModulePracticeQuestion
moduleId={moduleId}
questionNumber={questionIndex}
/>
<ModulePracticeAnswerArea
moduleId={moduleId}
questionNumber={questionIndex}
/>
</React.Fragment>
) : (
<h3>The menu should appear here!</h3>
)}
</div>
</div>
</div>
);
};
codesandbox

React router multiple <Switch>

I'm using "react-router-dom": "^4.3.1",, "#material-ui/core": "^3.9.2",
I got router.ts which has Route, Switch and MainPage component.
router.ts
<HashRouter>
<div id="App">
<Appbar />
<Switch>
<Route exact path="/" component={MainPage} />
<Route exact path="/signup" component={SignupPage} />
<Route exact path="/signup/success" component={SignupSuccessPage} />
<Route exact path="/room/:id" component={NovelPage} />
<Route component={NotfoundPage} />
</Switch>
</div>
</HashRouter>
And I got MainPage component which has Route and Switch
<AppBar position="static">
<Tabs
variant="fullWidth"
value={this.state.value}
indicatorColor="primary"
textColor="primary"
>
<Tab
label={"latest_novel"}
onChange={this.handleTabsChange(`/latest/novel`, 0)}
/>
<Tab
label={"create novel"}
onChange={this.handleTabsChange(`/create/room`, 1)}
/>
</Tabs>
<Switch>
<Route exact path={`${this.props.match.url}/latest/novel`} component={TodayNovelPage} />
<Route exact path={`${this.props.match.url}/create/room`} component={CreateRoomPage} />
</Switch>
</AppBar>
I expected
When I click Mainpage's Tab component then, page url is changed like "localhost:3000/latest/novel" and page is moved.
When page is moved then it shows under MainPage's Switch
But, when I tried it.
Page is moved but, Tabs is disappears and it seemed shows under the router.ts not Mainpage. Why is it?
Please let me know if you need more info.
Thanks.
You should have common parent route for both the tabs.
Please check below example which I have created.
https://codesandbox.io/s/zz2xnn9p7m
Index.js
import React from "react";
import ReactDOM from "react-dom";
import { Switch, Route, Redirect, BrowserRouter } from "react-router-dom";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import MainPage from "../src/mainPage";
import "./styles.css";
function App() {
return (
<div className="App">
<AppBar position="static">
<Toolbar>
<Typography variant="h6" color="inherit">
Relay Novel
</Typography>
</Toolbar>
</AppBar>
<BrowserRouter>
<Switch>
<Route exact path="/" render={() => <Redirect to="/mainPage" />} />
<Route path="/mainPage" component={MainPage} />
</Switch>
</BrowserRouter>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
MainPage.js
import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import { Switch, Route, Redirect, Link } from "react-router-dom";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { value } = this.state;
return (
<Fragment>
<Tabs value={value} onChange={this.handleChange}>
<Tab label="Latest Novel" component={Link} to="/mainPage/tab1" />
<Tab label="Create Novel" component={Link} to="/mainPage/tab2" />
</Tabs>
<Switch>
<Route exact path="/mainPage" />
<Route path="/mainPage/tab2" render={() => <div>Latest Novel</div>} />
<Route path="/mainPage/tab1" render={() => <div>Create Novel</div>} />
</Switch>
</Fragment>
);
}
}
export default MainPage;