Reactjs, Redux - redux-persist -


i working on reactjs/redux application - , using java spring boot codebase acting api.

i've got login system in place - notice when refresh page -- authentication state lost.

i've added redux-persist, doesn't appear take affect in stashing logged in state , resuming experience?

the bulk of redux-persist in place on router.js --- here store/provider gets set application.

i unsure how , store state when user has logged in -- i've exposed form login , can see start check this.props.authdata states -- ideal call persistor.rehydrate() -- don't have access persistor or store on pages?

//router.js

import react, { component } 'react' import { browserrouter router, route, redirect, switch } 'react-router-dom' import createbrowserhistory 'history/createbrowserhistory' import { provider } 'react-redux' import { createstore, applymiddleware } 'redux' import thunk 'redux-thunk'; import {persiststore, autorehydrate} 'redux-persist'  import rootreducer './reducers/rootreducer'  // components import login './components/login/login' import forgotpassword './components/forgotpassword/forgotpassword' import registeruser './components/registeruser/registeruser'  import home './components/home/home' import actions './components/actions/actions' import addsdq './components/actions/addsdq'  import pastsdq './components/pastsdq/pastsdq' import account './components/account/account'  import logout './components/logout/logout'  import './components/about/about' import terms './components/terms/terms' import privacy './components/privacy/privacy'  import error './components/error/error'  import header './components/header/header' import footer './components/footer/footer'  const history = createbrowserhistory()  // add `autorehydrate` enhancer store (note: `autorehydrate` not middleware) const store = createstore(     rootreducer,     applymiddleware(thunk),     autorehydrate() );  const persistor = persiststore(store, {}, () => {   console.log('restored'); })  // can pass lang files props routes // should have nested route inside service here show 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 store     /*     persiststore(store, {}, () => {       this.setstate({ rehydrated: true })       console.log("rehydrated", store);     })*/   }    render () {      console.log("this props", this);      // when user has logged in - navigate them home page     if(this.props.authdata){         //this.props.authdata.islogged       //return <redirect to='/home'/>;       console.log("user logged!!!!!!!!!!!");       //persistor.rehydrate()//calls reducer 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 } 'redux' import { reducer formreducer } 'redux-form'  import { authreducer } './authreducer' import { regreducer } './regreducer' import { forgotreducer } './forgotreducer' import { homereducer } './homereducer' import { editprofilereducer } './editprofilereducer' import { initprofilereducer } './initprofilereducer' import { editfollowupreducer } './editfollowupreducer' import { initfollowupreducer } './initfollowupreducer' import { addsdqreducer } './addsdqreducer' import { pastsdqreducer } './pastsdqreducer'  import { rehydratereducer } './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 

//rehydratereducer.js

import {rehydrate} '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}    } }  

//login.js

import react, { component } 'react' import { withrouter, redirect } 'react-router-dom'; //import { withrouter, redirect } 'react-router-dom'; import { connect } 'react-redux'; import { bindactioncreators } 'redux'; import { fetchauthentication } '../../actions/authaction';  import {persiststore} 'redux-persist'  import { row, col } 'antd';  // components import loginsyncvalidationform './loginsyncvalidationform'  import '../../forms.scss';   // class because 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 server side show message       if(this.props.authdata.data.data.status !== "success"){         errorplaceholder = this.props.authdata.data.data.msg;       }     }       // when user has logged in - navigate them home page     if(this.props.authdata.islogged){       //return <redirect to='/home'/>;        //persistor.rehydrate()//calls reducer rehydrate store     }       return (       <div classname="page form-components light">         <h2>login</h2>         <row>           <col xs={24} sm={24} md={10}>             <p>welcome slam sdq tracker. because accessing sensitive info, need verify identity using our secure login system. not protect data, provide platform can in control of progress. unique identification number has been sent e-mail. use login. if have not created account yet or have forgotten password, please use links below complete 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)) 

update 1: 14/09/2017

this authaction.js looks like

//authaction.js

    import axios '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 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 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 } '../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}    } } 

as per "steven daniel anderson" answer

"

const user = localstorage.getitem('user') if(user){     //set state authenticated true;     store.dispatch({         type:auth_user     }) } 

"

be more like

const user = localstorage.getitem('user') if(user){     //set state authenticated true;     authsuccess(user) } 

or in action create new function this

export function fetchresumeauth(data) {    dispatch(authsuccess(data)); } 

and in user check -- placed in router.js?

const user = localstorage.getitem('user') if(user){     //set state authenticated true;     fetchresumeauth(user) } 

you can use localstorage save user in browser:

localstorage.setitem('user',user) inside of action creator log in.

then create reducer set state true if user authenticated o false if not, this:

import { auth_user, unauth_user, error } '../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     }  } 

and last part verified if user authenticated each time reload page, in index.js file:

const user = localstorage.getitem('user') if(user){     //set state authenticated true;     store.dispatch({         type:auth_user     }) } 

note: can access user, using localstorage.getitem('user') in view.


Comments

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -