gpt4 book ai didi

Reactjs、Redux - redux-persist

转载 作者:行者123 更新时间:2023-12-03 13:54:10 25 4
gpt4 key购买 nike

我正在开发一个reactjs/redux应用程序 - 并使用Java Spring Boot代码库作为API。

我已经有了一个登录系统 - 但我注意到当我刷新页面时 - 身份验证状态丢失了。

我添加了 redux-persist,但它似乎对存储登录状态和恢复体验没有任何影响?

大部分 redux-persist 都位于我的 router.js 上——它是商店/提供程序设置为应用程序的地方。

我不确定用户登录后如何以及在哪里存储状态——我已经公开了登录表单,你可以看到我开始检查 this.props.authData 状态——它会在哪里调用 persistor.reHydrate() 是理想的选择——但是我无法访问这些页面上的持久器或存储?

//router.js

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk';
import {persistStore, autoRehydrate} from 'redux-persist'

import rootReducer from './reducers/rootReducer'

// components
import Login from './components/Login/Login'
import ForgotPassword from './components/ForgotPassword/ForgotPassword'
import RegisterUser from './components/RegisterUser/RegisterUser'

import Home from './components/Home/Home'
import Actions from './components/Actions/Actions'
import AddSDQ from './components/Actions/AddSDQ'

import PastSDQ from './components/PastSDQ/PastSDQ'
import Account from './components/Account/Account'

import Logout from './components/Logout/Logout'

import About from './components/About/About'
import Terms from './components/Terms/Terms'
import Privacy from './components/Privacy/Privacy'

import Error from './components/Error/Error'

import Header from './components/Header/Header'
import Footer from './components/Footer/Footer'

const history = createBrowserHistory()

// add `autoRehydrate` as an enhancer to your store (note: `autoRehydrate` is not a middleware)
const store = createStore(
rootReducer,
applyMiddleware(thunk),
autoRehydrate()
);

const persistor = persistStore(store, {}, () => {
console.log('restored');
})

// we can pass the lang files as props to the routes
// we should have a nested route inside service here to show the other services page

class Routes extends Component {

constructor (props) {
super(props)

/*
this.state = {
rehydrated: false
}*/
//console.log("router level", this.props)
//console.log("state-->", this.state)
}

componentWillMount(){
// begin periodically persisting the store
/*
persistStore(store, {}, () => {
this.setState({ rehydrated: true })
console.log("rehydrated", store);
})*/
}

render () {

console.log("this props", this);

// when the user has logged in - navigate them to the home page
if(this.props.authData){
//this.props.authData.isLogged
//return <Redirect to='/home'/>;
console.log("user logged!!!!!!!!!!!");
//persistor.rehydrate()//calls reducer to rehydrate store
}


const loggedIn = true;//this.state.isLoggedIn;
console.log("rendered store", store);

return (
<Provider store={store}>
<Router history={history}>
<div className='off-canvas-wrap' data-offcanvas>
<div className='inner-wrap'>
<Header transparent />
<Switch>
<Route path='/home' component={Home} />
<Route path='/past-sdq' component={PastSDQ} />
<Route path='/actions' component={Actions} />
<Route path='/add-sdq' component={AddSDQ} />

<Route path='/account' component={Account} />

<Route path='/about' component={About} />
<Route path='/terms' component={Terms} />
<Route path='/privacy' component={Privacy} />

<Route path='/login' component={Login} />
<Route path='/logout' component={Logout} />
<Route path='/forgot-password' component={ForgotPassword} />
<Route path='/register-user' component={RegisterUser} />

{/*<Route path='/api/:serviceRequest' />*/}

<Route exact path="/" render={() => ( loggedIn ? ( <Home/> ) : ( <Redirect to="/login"/> ) )} />

<Route component={Error} />
</Switch>
<Footer transparent />
</div>
</div>
</Router>
</Provider>
)
}
}

export default Routes

//rootReducer.js

import { combineReducers } from 'redux'
import { reducer as formReducer } from 'redux-form'

import { authReducer } from './authReducer'
import { regReducer } from './regReducer'
import { forgotReducer } from './forgotReducer'
import { homeReducer } from './homeReducer'
import { editProfileReducer } from './editProfileReducer'
import { initProfileReducer } from './initProfileReducer'
import { editFollowUpReducer } from './editFollowUpReducer'
import { initFollowUpReducer } from './initFollowUpReducer'
import { addSDQReducer } from './addSDQReducer'
import { pastSDQReducer } from './pastSDQReducer'

import { rehydrateReducer } from './rehydrateReducer'


const rootReducer = combineReducers({
form: formReducer,
auth: authReducer,
reg: regReducer,
forgot: forgotReducer,
home: homeReducer,
editProfile: editProfileReducer,
initProfile: initProfileReducer,
editFollowUp: editFollowUpReducer,
initFollowUp: initFollowUpReducer,
addSDQ: addSDQReducer,
pastSDQ: pastSDQReducer,
rehydrate: rehydrateReducer
})

export default rootReducer

//re HydroReducer.js

import {REHYDRATE} from 'redux-persist/constants'

export function rehydrateReducer (state = {}, action) {
//console.log('reducer REHYDRATE act', action)
switch (action.type) {
case REHYDRATE:
return {...state, data: action.payload};
default:
return {...state}
}
}

//登录.js

import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
//import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchAuthentication } from '../../actions/authAction';

import {persistStore} from 'redux-persist'

import { Row, Col } from 'antd';

// components
import LoginSyncValidationForm from './LoginSyncValidationForm'

import '../../forms.scss';


// this is a class because it needs state
class Login extends Component {

constructor(props, context) {
super(props, context);
this.submit = this.submit.bind(this);
}

/*
static propTypes = {
isDark: React.PropTypes.bool
}
static defaultProps = {
isDark: false
}
*/

componentDidMount() {
//document.body.classList.toggle('darkClass', this.props.isDark)
}
componentWillReceiveProps(nextProps) {
//document.body.classList.toggle('darkClass', nextProps.isDark)
}

componentWillMount () {
document.body.classList.add('screenbackground');
}

componentWillUnmount() {
document.body.classList.remove('screenbackground');
}

submit(data) {
this.props.fetchAuthentication(data);
}

render() {

var errorPlaceholder = "";

//console.log("authss-->", this.props.authData);
if(this.props.authData.data){

//console.log("status--<", this.props.authData.data.data.status);
//if error from server side show the message
if(this.props.authData.data.data.status !== "success"){
errorPlaceholder = this.props.authData.data.data.msg;
}
}


// when the user has logged in - navigate them to the home page
if(this.props.authData.isLogged){
//return <Redirect to='/home'/>;

//persistor.rehydrate()//calls reducer to rehydrate store
}

return (
<div className="Page form-components light">
<h2>Login</h2>
<Row>
<Col xs={24} sm={24} md={10}>
<p>Welcome to the SLAM SDQ tracker. Because you are accessing sensitive info, you need to verify your identity using our secure login system. This will not only protect your data, but will provide a platform where you can be in control of your progress. Your unique identification number has been sent to you by e-mail. Use it to login. If you have not created an account yet or have forgotten your password, please use the links below to complete the desired action.</p>
</Col>
<Col xs={24} sm={24} md={24}>
<Row>
<Col xs={24} sm={24} md={6}>
<LoginSyncValidationForm onSubmit={this.submit} />
</Col>
</Row>
</Col>
{errorPlaceholder.length > 0 &&
<Col xs={24} sm={24} md={24}>
{errorPlaceholder}
</Col>
}
</Row>
<div className="shell" />
<div className="screen-background login"/>
</div>
)
}

}

function mapStateToProps(state) {
return {
authData: state.auth
};
}

function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchAuthentication }, dispatch);
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Login))
<小时/>

更新 1:2017 年 9 月 14 日

这就是我的 authAction.js 的样子

//authAction.js

    import axios from 'axios';

export const FETCH_AUTH_SUCCESS = 'FETCH_AUTH_SUCCESS'
export const FETCH_AUTH_FAILURE = 'FETCH_AUTH_FAILURE'
export const FETCH_AUTH_CLEAR = 'FETCH_AUTH_CLEAR'

export function authSuccess(response) {
return {
type: FETCH_AUTH_SUCCESS,
payload: response
}
}

export function authFail(response) {
return {
type: FETCH_AUTH_FAILURE,
payload: response
}
}

export function authClear() {
return {
type: FETCH_AUTH_CLEAR,
payload: null
}
}


export function fetchAuthentication(data) {

let url = 'http://localhost:8080/login';

return function (dispatch) {
//axios.post(url, data)
axios.get(url, {
params: data
})
.then(function (response) {
console.log(response);

if(response.data.status === "success"){
dispatch(authSuccess(response));
}
else{
// fail - user not found for example
dispatch(authFail(response));
}

})
.catch(function (error) {
//console.log(error);
dispatch(authFail(error));
});
}
}


export function clearAuthentication() {

let url = 'http://localhost:8080/logout';

return function (dispatch) {
//axios.post(url, data)
axios.get(url)
.then(function (response) {
console.log(response);

if(response.data.status === "success"){
dispatch(authClear(response));
}
else{
// fail - user not found for example
dispatch(authFail(response));
}

})
.catch(function (error) {
//console.log(error);
dispatch(authFail(error));
});
}
}

//authReducer.js

import { FETCH_AUTH_SUCCESS, FETCH_AUTH_FAILURE, FETCH_AUTH_CLEAR } from '../actions/authAction'

export function authReducer (state = {}, action) {
//console.log('reducer act', action)
switch (action.type) {
case FETCH_AUTH_SUCCESS:
return {...state, data: action.payload, isLogged: true};
case FETCH_AUTH_FAILURE:
return {...state, data: action.payload, isLogged: false};
case FETCH_AUTH_CLEAR:
return {...state, data: action.payload, isLogged: false};
default:
return {...state}
}
}

根据“史蒂文·丹尼尔·安德森”的回答

"

const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
store.dispatch({
type:AUTH_USER
})
}

"

更像

const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
authSuccess(user)
}

或者在我的操作中创建一个像这样的新函数

export function fetchResumeAuth(data) {
dispatch(authSuccess(data));
}

然后在用户检查中——哪个将被放置在 router.js 中?

const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
fetchResumeAuth(user)
}

最佳答案

您可以使用 localStorage 在浏览器中保存用户:

localStorage.setItem('user',user) 在您的操作创建者中用于登录。

然后创建一个reducer,如果用户已通过身份验证,则将状态设置为true;如果没有,则将状态设置为false,如下所示:

import { AUTH_USER, UNAUTH_USER, ERROR } from '../actions/types'

export default function (state={}, action){
switch(action.type){
case AUTH_USER:
return { ...state, authenticated: true }
case UNAUTH_USER:
return { ...state, authenticated: false }
default:
return state
}

}

如果每次重新加载页面时都对用户进行身份验证,最后一部分将在 index.js 文件中进行验证:

const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
store.dispatch({
type:AUTH_USER
})
}

注意:您只需在任何 View 中使用 localStorage.getItem('user') 即可访问用户。

关于Reactjs、Redux - redux-persist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46208242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com