What is the difference between react-router and react-hash-router? - react-router

What is the main difference between <Router> and the <Hash-router> in react.js?
In my program, i put a form tag and mention a components path in action, but I used hash-router. I am not able to switch to "mentions component" but in case of router it switches to that other component.
Why is that, and what are the other difference between the two?
<HashRouter>
<div>
<h1>Simple SPA</h1>
<ul className="header">
<li><NavLink exact to="/">Home</NavLink></li>
<li><NavLink to="/stuff">Stuff</NavLink></li>
<li><NavLink to="/contact">Contact</NavLink></li>
</ul>
<div className="content">
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/stuff" component={Stuff}/>
<Route path="/contact" component={Contact}/>
</Switch>
</div>
</div>
</HashRouter>
The form:
<form action='/stuff'>
<label for="firstName"><b>FirstName</b></label>
<input type="text" name="fname" /><br/><br/>
<label for="lastName"><b>LastName</b></label>
<input type="text" name="lname"/><br/><br/>
<button type="submit" align="right">Signup</button>
</form>

Related

Closing Hamburger menu in React

i'm trying to close the hamburger menu onClick with react, but so far have no results :( Read a lot of similar questions here, but everyone html is different and none of the answers worked for me :( Here's the code, i know it should be done with with useState, but how can i do it ? It's the first condition, the second is just a search input for the start page
return (
<>
{city ?
<nav>
<input id="nav-toggle" type="checkbox" />
<div className="nav-input">
<form method='POST' type="text" className='form' onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
<ul className="links">
<li><NavLink to="/now" style={({ isActive }) =>
isActive ? active : undefined
}>Now</NavLink></li>
<li><NavLink to="/hourly" style={({ isActive }) =>
isActive ? active : undefined
}>Hourly</NavLink></li>
<li><NavLink to="/daily" style={({ isActive }) =>
isActive ? active : undefined
}>Daily</NavLink></li>
</ul>
<label htmlFor="nav-toggle" className="icon-burger">
<div className="line"></div>
<div className="line"></div>
<div className="line"></div>
</label>
{city ?
<div className='city-name'>
<p>weather at: </p>
<h4>{city}</h4>
</div>
: null}
</nav>
:
<>
<div className='nav-start-page'>
<div>
<h3>Get Your Forecast</h3>
</div>
<div>
<Link className='location-link' to="/location">
<img src={location} />
</Link>
</div>
<div>
<form method='POST' type="text" onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
</div>
</>
}
</>
);
};
Add a click event on hamburger menu and set menu list hidden by default from css
i.e; visiblity: hidden. And on menu click function get menu list div by id from js and set their css visiblity: visible
Use useState and a callback function to toggle the hamburger menu onClick.
Try this:
const [isOpen, setIsOpen] = useState(false);
return (
<>
{city ?
<nav>
<input id="nav-toggle" type="checkbox" onClick={() => setIsOpen(!isOpen)} />
<div className="nav-input">
<form method='POST' type="text" className='form' onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
{isOpen && <ul className="links">
<li><NavLink to="/now" style={({ isActive }) =>
isActive ? active : undefined
}>Now</NavLink></li>
<li><NavLink to="/hourly" style={({ isActive }) =>
isActive ? active : undefined
}>Hourly</NavLink></li>
<li><NavLink to="/daily" style={({ isActive }) =>
isActive ? active : undefined
}>Daily</NavLink></li>
</ul>}
<label htmlFor="nav-toggle" className="icon-burger">
<div className="line"></div>
<div className="line"></div>
<div className="line"></div>
</label>
{city ?
<div className='city-name'>
<p>weather at: </p>
<h4>{city}</h4>
</div>
: null}
</nav>
:
<>
<div className='nav-start-page'>
<div>
<h3>Get Your Forecast</h3>
</div>
<div>
<Link className='location-link' to="/location">
<img src={location} />
</Link>
</div>
<div>
<form method='POST' type="text" onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
</div>
</>
}
</>
);
};

How to render new page in react router v6 without adding other components?

I have a Login Button inside the Landing Page When I click the login button the component renders inside the Landing Page. What I want to do is render a new page how do I do that with react-router v6?
I'm Creating a Shop App
This is my App.js
import Header from "./components/Header";
import Intro from "./components/Intro";
import Shelf from "./components/Shelf";
function App() {
return (
<div>
<Header />
<Intro />
<Shelf />
</div>
);
}
export default App;
Here's the intro Component:
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Login from './Login';
import Signup from './Signup'
function Intro() {
return (
<div className="hero">
<div className="overlay column ai-center js-center">
<h1 className="m-0 fs-large"><em>Welcome to Furns</em></h1>
<hr />
<p className="m-0 fs-small">Worlwide known company serves the best furnitures</p>
<div className="row mt-4">
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
<Link to="/login">
<button className="login-btn-large px mx-3">Login</button>
</Link>
<Link to="/signup" >
<button className="sign-up-btn">Sign-up</button>
</Link>
</Router>
</div>
</div>
</div>
);
}
export default Intro;
And Here's my Login component:
import React from 'react';
function Login() {
return (
<div className="float shadow bg-light px-3 py-3 ai-center js-between">
<h2 className="brand color-olive">Furns</h2>
<h1 className="color-olive">Login</h1>
<form className="column">
<label htmlFor="username" className="color-olive my-1"> Username</label>
<input id="username" type="text" className="txt-box" />
<label htmlFor="password" className="color-olive my-1">Password </label>
<input id="password" type="password" className="txt-box" />
<button type="submit" className="mt-4 olive login-btn-large">Login</button>
<button className="my-1 olive bg-light btn-cancel" >Cancel</button>
</form>
</div>
);
}
export default Login;
This is how it looks like when I clicked the log in button
Login Component
If I am understanding your question and code correctly, Intro is what you are calling your landing page, and you want it to link to the other pages.
For this I suggest this refactor:
Render the Router and routes in App where Intro is currently being rendered.
Create a new route specifically for the landing intro page.
App
function App() {
return (
<Router>
<div>
<Header />
<Routes>
<Route path="/" element={<Intro />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
<Shelf />
</div>
</Router>
);
}
Intro
function Intro() {
return (
<div className="hero">
<div className="overlay column ai-center js-center">
<h1 className="m-0 fs-large"><em>Welcome to Furns</em></h1>
<hr />
<p className="m-0 fs-small">Worlwide known company serves the best furnitures</p>
<div className="row mt-4">
<Link to="/login">
<button className="login-btn-large px mx-3">Login</button>
</Link>
<Link to="/signup" >
<button className="sign-up-btn">Sign-up</button>
</Link>
</div>
</div>
</div>
);
}
If you don't want, or need, the Header and/or Shelf components to render on all pages then you can abstract these into a layout wrapper component that then renders an Outlet for wrapped routes to render into.
const PageLayout = () => (
<div>
<Header />
<Outlet />
<Shelf />
</div>
);
...
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Intro />} />
<Route path="/*" element={<PageLayout />} >
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Route>
</Routes>
</Router>
);
}

How to ignore hashrouter?

I have a simple hashrouter set up but when i press the button for my dropdown the content disapears, Is there a workaround ?
class App extends Component {
render () {
return (
<fragment>
<HashRouter>
<Navbar className="header">
<NavLink to="/Shop"> <NavItem icon={<IoIosBasket />} /> </NavLink>
<NavLink to="/Home"> <NavItem icon={<IoIosHome />} /> </NavLink>
<NavItem icon={<IoIosListBox />} />
<NavItem icon={<IoIosArrowDown />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
<div className="content">
<Route path="/Home" component={Home}/>
<Route path="/Shop" component={Shop}/>
// Test text
</div>
</HashRouter>
</fragment>
);
}
}

How to set the first name field on the same column as passport issue date

I am trying to create a Basic Details form. In this i wan all the input field to appear in a tabular format. Is there any way to do that without using table tag
I have tried using css properties like display:flex and flexDirection but it is not working.
return (
<>
{/* Main Container Div */}
<div
style={{
display: "flex",
justifyContent: "space-evenly"
}}
>
{/* First Row Div starts */}
<div
style={{
display: "flex",
justifyContent: "center",
flexDirection: "column"
}}
>
<div>
<img
src="http://cetra.in/test2/profile_image.png"
alt="Profile"
style={{ width: "150px", height: "150px" }}
/>
</div>
<div>
<Button variant="contained" color="primary">
Upload Photo
</Button>
</div>
</div>
<div>
{/* First Row */}
<div style={styles.row_container}>
<div style={styles.row_items}>
<InputLabel shrink>Age</InputLabel>
<Select
margin="dense"
value={this.state.select_value}
onChange={e => {
this.handle_change(e.target.value);
}}
>
<MenuItem value="ms">Ms</MenuItem>
<MenuItem value="mrs">Mrs</MenuItem>
<MenuItem value="mr">Mr</MenuItem>
<MenuItem value="miss">Miss</MenuItem>
</Select>
</div>
<div style={styles.row_items}>
<TextField label="First Name" />
</div>
<div style={styles.row_items}>
<TextField label="Last Name" />
</div>
</div>
{/* First Row Ends */}
{/* Second Row */}
<div style={styles.row_container}>
<div style={styles.row_items}>
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup
style={{
display: "flex",
flexDirection: "row"
}}
>
<FormControlLabel
control={<Radio />}
label="Male"
value="male"
/>
<FormControlLabel
control={<Radio />}
label="Female"
value="female"
/>
</RadioGroup>
</div>
<div style={styles.row_items}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker
clearable
value={null}
variant="inline"
label="Date of Birth"
/>
</MuiPickersUtilsProvider>
</div>
</div>
{/* Second Row Ends */}
{/* Third Row */}
<div style={styles.row_container}>
<div style={styles.row_items}>
<TextField label="Passport" />
</div>
<div style={styles.row_items}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker
clearable
value={null}
label="Passport Issue Date"
placeholder="Passport Issue Date"
/>
</MuiPickersUtilsProvider>
</div>
<div style={styles.row_items}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker
clearable
value={null}
label="Passport Expiration Date"
placeholder="Passport Expiration Date"
/>
</MuiPickersUtilsProvider>
</div>
</div>
{/* Third Row Ends */}
</div>
</div>
</>
);
I want the first name to appear as if it were in the same column as the passport issue date and second row should that is with two elements should have it's element on corners of that row.

How to fill fields with a single click on a table row with ReactJS

I am making an react application with a simple CRUD functionality. In my environment I use a framework called react bootstrap 2.
Link: https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html
I have a form that the user can fill the information:
<form id="car-form" onSubmit={this.handleSubmit}>
<input type="hidden" name="carId" />
<div className="row">
<div className="form-group col-sm-3">
<label>Brand</label>
<input type="text" className="form-control" placeholder="Enter brand" value={this.state.brand} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Model</label>
<input type="text" className="form-control" placeholder="Enter model" value={this.state.model} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>Color</label>
<input type="text" className="form-control" placeholder="Enter color" value={this.state.color} onChange={this.handleChange} />
</div>
</div>
<div className="row">
<div className="form-group col-sm-3">
<label>TopSpeed</label>
<input type="number" className="form-control" placeholder="Enter speed" value={this.state.topSpeed} onChange={this.handleChange} />
</div>
</div>
<div className="btn-group mr-2">
<button type="submit" className="btn btn-danger mr-1">Save changes</button>
<button type="reset" className="btn btn-danger mr-1">New record</button>
<button type="submit" className="btn btn-danger mr-1">Delete record</button>
</div>
</form>
The user can add a car and this working fine with the .NET core backend. I have a function from the official react bootstrap 2 documentation to select a row.
const rowEvents = {
onClick: (e, row, rowIndex) => {
console.log(`clicked on row with index: ${rowIndex}`);
}
};
When I click on a row I get the right index number. Now when I click on a row I want to fill the fields with data.
This is my handleChange method
handleChange(event) {
this.setState({
brand: event.target.brand,
model: event.target.model,
color: event.target.color,
topspeed: event.target.top
})
};
It still doesn't work when I click on a row.
How can I fill the fields when I click on a row?
Solution I used:
How do I programatically fill input field value with React?
assuming this.state.cars is where you storing the cars data . On clicking on the row change your function to
const rowEvents = {
onClick: (e, row, rowIndex) => {
this.setState({
brand: this.state.cars[rowIndex].brand,
model: this.state.cars[rowIndex].model,
color: this.state.cars[rowIndex].color,
topspeed: this.state.cars[rowIndex].top
})
}
};
and copy your rowEvents to render()