Reputation: 319
I have a simple app that has two pages: one for login and another for registration. I want them to have links to each other. As I know that React links have a different rationale, I'd lie to have the view of experienced colleagues regarding how to do it. This the code of login-view
:
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import axios from 'axios';
import './login-view.scss';
import { RegistrationView } from '../registration-view/registration-view';
export function LoginView(props) {
const [ username, setUsername ] = useState('');
const [ password, setPassword ] = useState('');
// need to update handleSubmit to prevent refresh
const handleSubmit = (e) => {
e.preventDefault();
/* Send a request to the server for authentication */
axios.post('https://flix-app-test.herokuapp.com/login', {
username: username,
password: password
})
.then(response => {
const data = response.data;
props.onLoggedIn(data);
})
.catch(e => {
console.log('no such user')
});
};
const handleNewUser = (e) => {
e.preventDefault();
console.log('new_user');
setUsername('New');
props.onLoggedIn(username);
};
return (
<div>
<h1>myFlix Login</h1>
<Form>
<Form.Group controlId="formBasicUsername">
<Form.Label>Username</Form.Label>
<Form.Control type="text" value={username} onChange={e => setUsername(e.target.value)} placeholder="Enter username" />
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" value={password} onChange={e => setPassword(e.target.value)} placeholder="Password" />
</Form.Group>
<Button onClick={handleSubmit}>Submit</Button>
</Form>
</div>
);
}
LoginView.propTypes = {
username: PropTypes.string.isRequired,
password: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired
};
Here is the code of registration-view
:
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import { LoginView } from '../login-view/login-view';
import './registration-view.scss';
export function RegistrationView(props) {
const [ username, setUsername ] = useState('');
const [ password, setPassword ] = useState('');
const [email, setEmail ] = useState('');
const [birthday, setBirthday ] = useState('');
// need to update handleSubmit to prevent refresh
const handleSubmit = (e) => {
e.preventDefault();
console.log(username, password, email, birthday);
/* Send a request to the server for authentication */
/* then call props.onLoggedIn(username) */
props.onLoggedIn(username);
};
return (
<div>
<h1>Signup for myFlix</h1>
<Form>
<Form.Group controlId="formUsername">
<Form.Label>Username</Form.Label>
<Form.Control type="text" value={username} onChange={e => setUsername(e.target.value)} placeholder="Enter the username you want to use" />
</Form.Group>
<Form.Group controlId="formPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="text" value={password} onChange={e => setPassword(e.target.value)} placeholder="Enter a password" />
</Form.Group>
<Form.Group controlId="formEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="Enter email" />
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
<Form.Group controlId="formBirthday">
<Form.Label>Password</Form.Label>
<Form.Control type="date" value={birthday} onChange={e => setBirthday(e.target.value)} placeholder="Enter your birthday date" />
</Form.Group>
</Form.Group>
<Button onClick={handleSubmit}>Submit</Button>
</Form>
</div>
);
}
RegistrationView.propTypes = {
username: PropTypes.string.isRequired,
password: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
birthday: PropTypes.string,
onClick: PropTypes.func.isRequired
};
I am allowed to use any package like react-router-dom
so no restrictions at all. Thanks in advance.
Upvotes: 1
Views: 10524
Reputation: 1
I Believe we can use react-scroll
import * as Scroll from 'react-scroll';
import { Link, Element } from 'react-scroll'';
<ScrollLink to="footerContainer">
<Button className="hero-content-button" variant="info">Know More</Button>
</ScrollLink>
<Element name="footerContainer">
<Footer />
</Element>
ScrollLink
is imported from react-scroll
which will link the button to footerContainer
everytime the button is clicked screen will scroll down to footer component
Upvotes: 0
Reputation: 21327
You could easily achieve that using react-router
. First in a component which lies on top of the tree (usually App
) you configure your Router, mapping each path
to a specific component
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { Login, Registration } from './components'
const App = () =>{
return(
<Router>
<Route path='/login' component={Login} />
<Route path='/registration' component={Registration} />
</Router>
)
}
Now to change between routes inside your components you have several options. One of them is Link
component
import { Link } from 'react-router-dom'
const Login = () =>{
return(
<Link to='/registration'>
Go to registration
</Link>
)
}
To a more imperative API you should know that every component rendered by a router is injected with special props: history
, match
and location
. To change the current route from inside a handler you can use history.push
const handleClick = () =>{
props.history.push('/registration')
}
The path to the components syntax on is supposed to be the same one I use to import the components?
Not it doesn't. The absolute path of your components has nothing to do with the path
provided to Router
import { Foo } from './foo'
/*...*/
<Route path='/bar' />
When implementing
Login
if I try to render it, it says I should not use link outside router
I forgot to mention that to use Link
you must be inside a Router context. Which means that the component from where you're calling Link
(in your case Login
) must be rendered by a router. In other words, it must be routed, defined inside one of your Route
components.
Upvotes: 6