Programing

로그인 후 재연결(React.js)

c10106 2022. 4. 8. 18:38
반응형

로그인 후 재연결(React.js)

며칠 전부터 내 App.js에서 콜백 기능을 생성하여 로그인 등록 페이지 클래스 구성 요소를 통해 로그인 클래스 구성 요소에 소품으로 전송한 후 사용자를 리디렉션하려고 시도했지만, 작동하지 않습니다만, 누군가가 해당 항목을 보고 누락된 내용을 알려 주시겠습니까?고마워 내 코드는 이렇게 생겼어

앱.js

import React from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import { HomePage } from './Pages/HomePage/HomePage'
import { LoginRegisterPage } from './Pages/LoginRegisterPage/LoginRegisterPage'
import 'bootstrap/dist/css/bootstrap.min.css'

export class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      authenticated: false,
    }
    this.handleSuccess = this.handleSuccess.bind(this);

  }
  handleSuccess = (data) => {
    this.props.history.push("/")
  }

  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/">
            <HomePage />
          </Route>
          <Route exact path="/login-register">
            <LoginRegisterPage onLoginSuccess={this.handleSuccess} />
        </Switch>
      </Router>
    )
  }
}

LoginRegisterPage 클래스 구성 요소

class LoginPage extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: '',
            accessToken: '',
            authenticated: ''
        };
        this.handleChangeUsername = this.handleChangeUsername.bind(this);
        this.handleChangePassword = this.handleChangePassword.bind(this);

    }

    handleChangeUsername(event) {
        this.setState({
            username: event.target.value
        })
    }

    handleChangePassword(event) {
        this.setState({
            password: event.target.value
        })
    }

    handleClick(event) {
        var apiBaseUrl = "https://myapi.com/auth/"
        const payload = {
            method: "POST",
            headers: {
                'Content-Type': 'application/json; charset=utf-8'
            },
            body: JSON.stringify({
                'username': this.state.username,
                'password': this.state.password
            })
        };
        const { username, password } = this.state;

        if (username && password) {
            fetch(apiBaseUrl + 'login', payload)
                .then((response) => {
                    if (response.status === 200) {
                        alert("Logged In! You'll be redirected on Home")
                        return response.json()
                    } else {
                        return alert("wrong pass")
                    }
                }).then((data) => {
                    this.setState({
                        accessToken: data.accestToken,
                        authenticated: data.authenticated
                    });
                    localStorage.setItem('accessToken', data.accessToken);
                    if (data.authenticated === true) {
                        console.log(this.props)
                        this.props.onLoginSuccess(data)
                    }

                })
                .catch((err) => console.log(err));
        } else {
            alert("Cannot be Empty")
        }
    }

    render() {
        return (
            <div>
                <div className="form">
                    <div>
                        <div className="form-input">
                            <div >
                                <div className="userData">
                                    <span>
                                        <img
                                            src={UserIcon}
                                        />
                                    </span>
                                    <input
                                        autocomplete="off"
                                        type="text"
                                        name="username"
                                        placeholder="Username"
                                        value={this.state.username}
                                        onChange={this.handleChangeUsername}
                                    />
                                </div>
                                <div className="userData">
                                    <span>
                                        <img
                                            src={PasswordIcon}
                                        />
                                    </span>
                                    <input
                                        autocomplete="off"
                                        type="password"
                                        name="password"
                                        placeholder="Password"
                                        value={this.state.password}
                                        onChange={this.handleChangePassword}
                                    />
                                    <p style={(this.state.username && this.state.password) ? { display: 'none' } : { display: 'block' }}> Must fill all the form!</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="form-footer">
                    <img
                        src={Btn}
                        onClick={(event) => this.handleClick(event)}
                    />
                </div>
            </div>
        );
    }
}

LoginPage 클래스 구성 요소

class LoginPage extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: '',
            accessToken: '',
            authenticated: ''
        };
        this.handleChangeUsername = this.handleChangeUsername.bind(this);
        this.handleChangePassword = this.handleChangePassword.bind(this);

    }

    handleChangeUsername(event) {
        this.setState({
            username: event.target.value
        })
    }

    handleChangePassword(event) {
        this.setState({
            password: event.target.value
        })
    }

    handleClick(event) {
        var apiBaseUrl = "https://movies-app-siit.herokuapp.com/auth/"
        const payload = {
            method: "POST",
            headers: {
                'Content-Type': 'application/json; charset=utf-8'
            },
            body: JSON.stringify({
                'username': this.state.username,
                'password': this.state.password
            })
        };
        const { username, password } = this.state;

        if (username && password) {
            fetch(apiBaseUrl + 'login', payload)
                .then((response) => {
                    if (response.status === 200) {
                        alert("Logged In! You'll be redirected on Home")
                        return response.json()
                    } else {
                        return alert("wrong pass")
                    }
                }).then((data) => {
                    this.setState({
                        accessToken: data.accestToken,
                        authenticated: data.authenticated
                    });
                    localStorage.setItem('accessToken', data.accessToken);
                    if (data.authenticated === true) {
                        console.log(this.props)
                        this.props.onLoginSuccess(data)
                    }

                })
                .catch((err) => console.log(err));
        } else {
            alert("Cannot be Empty")
        }
    }

    render() {
        return (
            <div>
                <div className="form">
                    <div>
                        <div className="form-input">
                            <div >
                                <div className="userData">
                                    <span>
                                        <img
                                            src={UserIcon}
                                        />
                                    </span>
                                    <input
                                        autocomplete="off"
                                        type="text"
                                        name="username"
                                        placeholder="Username"
                                        value={this.state.username}
                                        onChange={this.handleChangeUsername}
                                    />
                                </div>
                                <div className="userData">
                                    <span>
                                        <img
                                            src={PasswordIcon}
                                        />
                                    </span>
                                    <input
                                        autocomplete="off"
                                        type="password"
                                        name="password"
                                        placeholder="Password"
                                        value={this.state.password}
                                        onChange={this.handleChangePassword}
                                    />
                                    <p style={(this.state.username && this.state.password) ? { display: 'none' } : { display: 'block' }}> Must fill all the form!</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="form-footer">
                    <img
                        src={Btn}
                        onClick={(event) => this.handleClick(event)}
                    />
                </div>
            </div>
        );
    }
}

Ract Router를 사용하는 경우 Redirect 구성 요소를 사용하십시오.

import { Redirect } from 'react-router-dom';

export default function PrivateRoute () {
  if (notLoggedIn()) {
    return <Redirect to="/login"/>;
  }
  // return your component
}

그러나 렌더 함수에 없거나(즉, 제출 콜백 중) 브라우저 기록을 다시 작성하려면useHistory후크(참고: 후크는 클래스 구성요소가 아닌 기능 구성요소에서만 작동)

import { useHistory } from 'react-router-dom';


const history = useHistory();

// After your login action you can redirect with this command:
history.push('/otherRoute');

이슈

App외부로 정의된다.Router구성 요소, 즉 구성 요소가 없으므로history어떤 항법 수술이든 호출할 수 있는 프로펠러 기능

해결책

가지고 있다LoginRegisterPage구성 요소 인증 성공 시 탐색그것은 접근해야 할 필요가 있을 것이다.history가장 가까운 물건Router문맥의일반적으로 이는 에서 통과된 경로 소품들을 소비함으로써 달성된다.Route구성 요소

다음 작업을 수행할 수 있음:

#1

이동하다LoginRegisterPage…에 의해 인도되다component의 소품.Route그래서 경로 소품들을 받아서history버팀목으로서 반대하다

<Route exact path="/login-register" component={LoginRegisterPage} />

LoginRegisterPage

class LoginPage extends React.Component {
    constructor(props) {
        ...
    }

    ...

    handleClick(event) {
        var apiBaseUrl = "https://myapi.com/auth/"
        const payload = {...};
        const { username, password } = this.state;
        const { history } = this.props; // <-- destructure history from props

        if (username && password) {
            fetch(apiBaseUrl + 'login', payload)
                .then((response) => {
                    ...
                }).then((data) => {
                    this.setState({
                        accessToken: data.accestToken,
                        authenticated: data.authenticated
                    });
                    localStorage.setItem('accessToken', data.accessToken);
                    if (data.authenticated === true) {
                        console.log(this.props)
                        this.props.history.push("/"); // <-- navigate!
                    }

                })
                .catch((err) => console.log(err));
        } else {
            alert("Cannot be Empty")
        }
    }

    render() {
        ...
    }
}

#2

꾸미기LoginRegisterPageRouter Higher Order Component를 사용하여 경로 소품을 소품으로 주입할 수 있음.

import { withRouter } from 'react-router-dom;

...

const LoginPageWithRouter = withRouter(LoginPage);

참고

리디렉션을 수행하려는 경우 다음 항목을 바꾸십시오.history.push와의 통화.history.replace.push정상적인 항법 수술로 기록 상태에서 새로운 경로를 밟는 반면replace스택의 현재 기록 항목을 대체하십시오.인증 리디렉션 후에는 사용자가 로그인 페이지/루트로 다시 이동하는 것을 원하지 않을 수 있다.

편집

만약 당신이 필요하다면handleSuccess다음에서 일부 인증 상태를 관리하기 위해 콜백App그럼 그냥 놔두는 게 좋을 것 같아App인증 상태 및 관리LoginPage항해를 계속하다이 경우 위의 두 번째 솔루션으로 이동하여 두 가지 솔루션을 모두 수신하십시오.handleSuccess콜백 앤 더history이의를 제기하다

if (data.authenticated === true) {
  this.props.onLoginSuccess(data); // <-- callback to parent to set state
  this.props.history.replace("/"); // <-- imperative navigation
}

소품으로 전달하지 않고 LoginRegisterPage에서handleSucess기능을 정의하십시오.이기능이 작동해야 한다.

참조URL: https://stackoverflow.com/questions/66115064/redirect-after-login-react-js

반응형