Next.js принцип поведения страниц и контроллеров
Всем привет! Работаю с Next.js совсем чуть-чуть. И я не нашел статейки которая объяснила бы всю структуру приложений на Next. Одни сплошные "давайте создадим блог". У меня ситуация когда бэк у меня готов в виде api а next-app должен всего-лишь кидать запрос, принимать ответ, отображать данные.
Покажу страницу моей авторизации XD да-да, я знаю она ужасна =)
import { Component } from 'react'
import fetch from 'isomorphic-unfetch'
import { auth } from '../../utils/auth'
class Login extends Component {
static getInitialProps({ req }) {
const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http'
const host = `localhost:3001`
const apiUrl = `${protocol}://${host}/admin/account/login`
return { apiUrl }
}
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
code: '',
preToken: '',
isPreAuth: true,
isAuth: false,
isLoad: false,
error: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
console.log({ [event.target.name]: event.target.value })
this.setState({ [event.target.name]: event.target.value })
}
async handleSubmit(event) {
event.preventDefault()
try {
let response;
this.setState({ error: '', isLoad: true })
if (this.state.isPreAuth) {
response = await fetch(`http://localhost:3001/admin/account/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(`email=${this.state.email}&password=${this.state.password}`)
})
} else {
response = await fetch(`http://localhost:3001/admin/account/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(`preToken=${this.state.preToken}&code=${this.state.code}`)
})
}
if (response.ok) {
const request = await response.json()
const token = request.values.token;
auth({ token })
this.setState({ isAuth: true, isPreAuth: false, isLoad: false, preToken: token })
} else {
console.log('Login failed.')
this.setState({ error: 'Login failed.', isLoad: false })
}
} catch (error) {
console.error(
'You have an error in your code or there are Network issues.',
error
)
throw new Error(error)
}
}
render() {
return (
<>
<div id="login_container">
<div id="login_block">
{this.state.isLoad &&
<span id="loader"><i className="loading_a"></i></span>}
<form onSubmit={this.handleSubmit} className="auth">
{this.state.isPreAuth &&
<input
type='email'
id='email'
name='email'
placeholder="Имя аккаунта"
value={this.state.username}
onChange={this.handleChange}
/>}
{this.state.isPreAuth &&
<input
type='password'
id='password'
name='password'
placeholder="Пароль"
value={this.state.password}
onChange={this.handleChange}
/>
}
{this.state.isAuth &&
<input
type='text'
id='code'
name='code'
placeholder="PIN код"
value={this.state.code}
onChange={this.handleChange}
/>
}
<div className="login_control">
<button type='submit'>Login</button>
<p className={`error ${this.state.error && 'show'}`}>
{this.state.error && `Error: ${this.state.error}`}
</p>
</div>
</form>
</div>
</div>
<style jsx>{`
#login_container {
display: flex;
width: 100vw;
height: 100vh;
justify-content: center;
align-items: center;
}
#login_block {
display: block;
width: 20rem;
border-radius: 10px;
background-color: white;
-webkit-box-shadow: 0px 1px 2px 1px rgb(216, 216, 216);
-moz-box-shadow: 0px 1px 2px 1px rgb(216, 216, 216);
box-shadow: 0px 1px 2px 1px rgb(216, 216, 216);
}
.auth {
margin: 20px 0;
}
input {
width: 270px;
margin: 10px 25px;
border-radius: 3px;
border: 1px solid #d6d6d6;
height: 35px;
padding-left: 25px;
box-sizing: border-box;
}
.login_control {
margin: 10px 25px;
}
button {
padding: 7px 16px 8px;
cursor: pointer;
line-height: 20px;
background-color: #3f8cb5;
color: #fff;
border: 0;
border-radius: 4px;
}
p {
display: inline;
line-height: 35px;
margin-left: 25px;
}
#loader {
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
background: #ffffffc7;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.loading_a {
animation: rotation 1s infinite linear;
border: 1px solid rgba(156, 156, 156, 0.2);
border-radius: 50%;
border-top-color: rgba(58, 58, 58, 0.7);
height: 3rem;
width: 3rem;
}
@keyframes rotation {
to {
transform: rotate(360deg);
}
}
`}</style>
</>
)
}
}
export default Login
по факту тут есть 2 стадии страницы login.
- Ввод логина и пароля, получение предварительного токена ( api в этот момент отправляет пин код для входа на почту ).
- После получения предварительного токена поля логина и пароля меняется на поле для пина. и при нажатии на ту же кнопку отправляется запрос на другой адрес api.
Я подумал что 2 формы ( логин и пасс / пин код ) вывести стоит в компоненты. Но тут еще больше вопросов. Как страница login должна понимать что предварительный токен получен и пора вывести вторую форму.
Вообщем я понимаю что четкого вопроса сформулировать тут не получается... Буду благодарен за указания на ошибки и подсказки по реализации правильных приложений на react
Ответы (1 шт):
Переходите на реакт-хуки, они проще.
const [send, setSend] = useState(false)
const sendForm = () => {
// отправляем форму
setSend(true) // Теперь страница знает что форма была отправлена
}
return (
<div>
{!send && <div>форма логина</div>} // отображается если форма не была отправлена
{send && <div>форма ввода токена с почты</div>} // наоборот
</div>
)