저는 React에서 배우고 연습하기 시작했습니다. 제 생각은 로그인 화면을 만드는 것이 었는데, 여기서 나머지 API를 호출하고 사용자를 메모리에 저장하고, 로그인 할 때 사용자를 홈으로 리디렉션했습니다. 문제는 사용자가 로그인하면 로그인 화면을 볼 수 없다는 것입니다. 이렇게하려면 "isLogged"상태를 "login"구성 요소에 보내고 사용자가 "Logged"상태이면 리디렉션하려고합니다. 문제는 상태가 올바르게되지 않는다는 것입니다.
app.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom'
import './App.css';
import Login from './Pages/Login/Login'
import Logout from './Pages/Logout/Logout'
import Home from './Pages/Home/Home'
export default class App extends Component{
constructor(){
super();
this.state = {
loggedIn: "no-logueado",
user:{},
};
this.handleLogin = this.handleLogin.bind(this);
this.handleLogout = this.handleLogout.bind(this);
this.loggedIn = this.loggedIn.bind(this);
}
handleLogin(data){
this.setState({
loggedIn: "Logueado",
user: data
});
}
handleLogout(){
this.setState({
loggedIn: "no-logueado",
user: {}
});
}
isLoggedin(){
const token = localStorage.getItem("authToken");
if(this.state.loggedIn === "no-logueado" && token){
this.setState({
loggedIn: "Logueado",
user: token
});
}
}
loggedIn(data){
if(data === "Logueado"){
window.location="/home";
}
}
async componentDidMount(){
await this.isLoggedin();
}
render() {
return (
<Router>
<Route exact path="/" render={props => ( <Login {... props} handleLogin={this.handleLogin} loggedIn={this.state.loggedIn}/>)} />
<Route exact path="/logout" render={props => ( <Logout {... props} handleLogout={this.handleLogout}/>)} />
<Route exact path="/home" render={props => (<Home {... props} loggedIn={this.loggedIn} log={this.state.loggedIn}/>)} />
<script src="https://unpkg.com/react/umd/react.production.min.js" crossorigin></script>
<script
src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"
crossorigin></script>
<script
src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"
crossorigin></script>
<script>var Alert = ReactBootstrap.Alert;</script>
</Router>
);
}
}
로그인
import React, { Component } from 'react'
import Input from './Components/Input/input'
import Label from './Components/Label/Label'
import 'bootstrap/dist/css/bootstrap.min.css';
import './Login.css'
import {Container, Row, Col, Button} from 'react-bootstrap'
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
user:' ',
password:' '
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleSuccessfullAuth = this.handleSuccessfullAuth.bind(this);
}
handleChange(name, value) {
if(name==='username'){
this.setState({user:value});
} else {
this.setState({password:value});
}
}
async handleSubmit(){
const requestOptions = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: this.state.user,
password:this.state.password
})
};
const response = await fetch('http://localhost:4000/login', requestOptions);
console.log(response.ok);
if(response.ok){
const res = await response.json();
localStorage.setItem("authToken", res.token)
this.handleSuccessfullAuth(res);
} else {
console.log("token", localStorage.getItem("authToken"))
}
}
handleSuccessfullAuth(data){
this.props.handleLogin(data);
this.props.history.push("/home");
}
componentDidMount(){
console.log(this.props.loggedIn)
}
render(){
return (
<div id="login-background">
<Container>
<Row>
<Col xs={6}>
<Col xs={8} className="back">
<h2 className="tittle-login">¡ Bienvenido !</h2>
<h2 className="tittle-login">{this.props.loggedIn}</h2>
<hr className="hr-design"></hr>
<Label text='Usuario'/>
<Input attribute= {{
id: 'username',
name:'username',
type:'text',
placeholder:'Ingrese su usuario ...',
className:'form-control'
}}
handleChange={this.handleChange}
/>
<Label text='Contraseña'/>
<Input attribute= {{
id: 'password',
name:'password',
type:'password',
placeholder:'Ingrese su contraseña ...',
className:'form-control'
}}
handleChange={this.handleChange}
/><br></br>
<Button variant="primary" size="lg" block onClick={this.handleSubmit}>Iniciar Sesión</Button>{' '}
</Col>
<Col xs={4}>
</Col>
</Col>
<Col>
</Col>
</Row>
</Container>
</div>
)
}
}
콘솔을 통해 상태가 "로그인"에 도달하는 방법을 볼 때 화면에 "로그인"이 표시되지만 "로그인하지 않음"으로 표시됩니다.
먼저 배워야 할 게 있거나 놓친 게있는 것 같아요. 도와 줄 수 있나요?
"Logueado"를 렌더링하지만 콘솔에서 "No-logueado"상태를 얻습니다.
집
import React, { Component } from 'react'
import Menu from '../../Components/Menu'
export default class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Menu/>
</div>
)
}
}
사용자가 로그인 한 경우에서 Redirect
구성 요소를 사용하여 'react-router-dom'
로그인 페이지에서 홈 페이지로 리디렉션 할 수 있습니다 .
render()
함수 안에 조건부 반환을 추가하기 만하면 됩니다.
render() {
if (this.props.loggedIn === STATE_LOGGED_IN) {
return <Redirect path="/home" />;
}
return (
<div id="login-background">
<Container>
...
또한 자유롭게 구성 요소를 리팩토링 할 수있었습니다. 몇 가지 제안이 있습니다.
첫째, 바인딩이 필요한 클래스 메서드 대신 화살표 함수를 사용할 수 있습니다. 화살표 함수에는 this
키워드 가 없으므로 바인딩이 필요하지 않습니다.
handleLogin = (data) => {
this.setState({
loggedIn: STATE_LOGGED_IN,
user: data,
});
};
둘째, 렌더링 children
형식 을 사용하는 것이 좋습니다 <Route>
. 훨씬 깨끗하고 읽기 쉽습니다.
<Router>
<Route exact path="/">
<Login handleLogin={this.handleLogin} loggedIn={this.state.loggedIn} />
</Route>
<Route exact path="/logout">
<Logout handleLogout={this.handleLogout} />
</Route>
<Route exact path="/home">
<Home loggedIn={this.state.loggedIn} />
</Route>
</Router>
을 호출 한 함수를 제거했음을 알 수 있습니다 window.location="/home"
. react-router-dom
직접 수정하는 대신 위치 변경 에 사용 하는 것이 좋습니다 window.location
.
마지막으로, 문자열 'Logueado'
과 'no-logueado'
문자열 을 const 문자열로 지정하는 것이 좋습니다. const를 사용하면 문자열을 잘못 입력하는 문제를 방지 할 수 있습니다.
export const STATE_LOGGED_IN = 'Logueado';
export const STATE_LOGGED_OUT = 'no-logueado';
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import Login from './Pages/Login/Login';
import Logout from './Pages/Logout/Logout';
import Home from './Pages/Home/Home';
export const STATE_LOGGED_IN = 'Logueado';
export const STATE_LOGGED_OUT = 'no-logueado';
export default class App extends Component {
constructor() {
super();
this.state = {
loggedIn: STATE_LOGGED_OUT,
user: {},
};
}
componentDidMount() {
this.isLoggedin();
}
handleLogin = (data) => {
this.setState({
loggedIn: STATE_LOGGED_IN,
user: data,
});
};
handleLogout = () => {
this.setState({
loggedIn: STATE_LOGGED_OUT,
user: {},
});
};
isLoggedin = () => {
const token = localStorage.getItem('authToken');
if (this.state.loggedIn === STATE_LOGGED_OUT && token) {
this.setState({
loggedIn: STATE_LOGGED_IN,
user: token,
});
}
};
render() {
return (
<Router>
<Route exact path="/">
<Login handleLogin={this.handleLogin} loggedIn={this.state.loggedIn} />
</Route>
<Route exact path="/logout">
<Logout handleLogout={this.handleLogout} />
</Route>
<Route exact path="/home">
<Home loggedIn={this.state.loggedIn} />
</Route>
</Router>
);
}
}
render 메서드에서 조건부 반환을 확인하십시오.
import React, { Component } from 'react';
import Input from './Components/Input/input';
import Label from './Components/Label/Label';
import 'bootstrap/dist/css/bootstrap.min.css';
import './Login.css';
import { Container, Row, Col, Button } from 'react-bootstrap';
import { STATE_LOGGED_IN, STATE_LOGGED_OUT } from '../../App';
import { Redirect } from 'react-router';
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
user: ' ',
password: ' ',
};
}
componentDidMount() {
console.log(this.props.loggedIn);
}
handleChange = (name, value) => {
if (name === 'username') {
this.setState({ user: value });
} else {
this.setState({ password: value });
}
}
async handleSubmit = () => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: this.state.user,
password: this.state.password,
}),
};
const response = await fetch('http://localhost:4000/login', requestOptions);
console.log(response.ok);
if (response.ok) {
const res = await response.json();
localStorage.setItem('authToken', res.token);
this.handleSuccessfullAuth(res);
} else {
console.log('token', localStorage.getItem('authToken'));
}
}
handleSuccessfullAuth = (data) => {
this.props.handleLogin(data);
this.props.history.push('/home');
}
render() {
if (this.props.loggedIn === STATE_LOGGED_IN) {
return <Redirect path="/home" />;
}
return (
<div id="login-background">
<Container>
<Row>
<Col xs={6}>
<Col xs={8} className="back">
<h2 className="tittle-login">¡ Bienvenido !</h2>
<h2 className="tittle-login">{this.props.loggedIn}</h2>
<hr className="hr-design"></hr>
<Label text="Usuario" />
<Input
attribute={{
id: 'username',
name: 'username',
type: 'text',
placeholder: 'Ingrese su usuario ...',
className: 'form-control',
}}
handleChange={this.handleChange}
/>
<Label text="Contraseña" />
<Input
attribute={{
id: 'password',
name: 'password',
type: 'password',
placeholder: 'Ingrese su contraseña ...',
className: 'form-control',
}}
handleChange={this.handleChange}
/>
<br></br>
<Button variant="primary" size="lg" block onClick={this.handleSubmit}>
Iniciar Sesión
</Button>{' '}
</Col>
<Col xs={4}></Col>
</Col>
<Col></Col>
</Row>
</Container>
</div>
);
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다