2017-09-08 47 views
1

很多我的組件會根據用戶是否登錄而改變他們的行爲方式。如果用戶在React中登錄,全局追蹤方式?

當本地存儲具有有效的jwt令牌時,用戶已登錄。

我可以添加一個'isLoggedIn'布爾值來關心這個並初始化它的所有組件的狀態,但是這會引入很多冗餘。

有沒有一種方法可以讓所有組件都可以輕鬆訪問並處理這個全局道具或狀態?也許即使在'isLoggedIn'之後的將來,我還會得到關於用戶的其他信息,例如用戶名和事物?

+0

我假設你有'window.jwt'令牌?如果是這樣,只需從那裏直接閱讀。你不需要在你的狀態下擁有。 – Chris

+0

你有Redux在這裏標記。你應該可以使用它。你有任何我們可以幫助你的Redux代碼嗎? –

+0

@Chris我在render函數中嘗試使用localStorage.GetItem('jwt'),但是我得到一個關於localstorage未定義的錯誤,所以我認爲這不是一個選項。 – tweetypi

回答

1

我在我的一個項目中有非常類似的要求。

store.dispatch(tryAuthenticateFromToken()); 

ReactDOM.render(
    <Provider store={store}> 
    <Router history={browserHistory} /> 
    </Provider>, 
    document.getElementById('root') 
); 

我的解決方案是在渲染之前將登錄事件發送到商店。 你可以做類似的事情。

然後在reducer中解析該事件並將商標中的令牌保存在某處。 之後,您可以將其作爲商店中的任何其他變量使用,並將其傳遞給「對應組件」以根據登錄狀態進行不同的呈現。

1

我不知道REDX和IM試圖迫使這樣的應用程序重新渲染,如果你能告訴我關於這個解決方案的潛在缺陷,我會很高興聽到它!

class App extends React.Component { 
 

 
    constructor(props){ 
 
    super(props); 
 

 
    this.updateCurrentUser = this.updateCurrentUser.bind(this) 
 

 
    this.state = { 
 

 
     currentUser:new CurrentUser(this.updateCurrentUser) 
 

 
    } 
 
    this.logUser = this.logUser.bind(this) 
 
    } 
 

 
    render() { 
 

 
    return (
 

 
     <div> 
 

 
     <h4>{"User is logged " + (this.state.currentUser.isLoggedIn()?'in':'out')}</h4> 
 
     <button onClick={this.logUser}>Log in</button> 
 
     </div> 
 

 
    ); 
 

 

 
    } 
 
    
 
    logUser(){ 
 
    
 
    this.state.currentUser.logIn(); 
 
    
 
    } 
 

 
    updateCurrentUser(currentUser){ 
 

 
    this.setState({ 
 

 
     currentUser:currentUser 
 

 
    }) 
 

 
    } 
 

 
    getCurrentUser(){ 
 

 
    return this.state.currentUser 
 

 
    } 
 

 
} 
 

 
class CurrentUser { 
 

 
    constructor(onChange){ 
 
    
 
    this._isLoggedIn = false; 
 
    this.onChange = onChange 
 
    this.logIn = this.logIn.bind(this); 
 
    } 
 

 
    /** 
 
    * Log user into the web app 
 
    * @param {string} email 
 
    * @param {string} password 
 
    * @param {function} success callback 
 
    * @param {function} fail  callback 
 
    * @return {void} 
 
    */ 
 
    logIn(){ 
 

 
    //fake request 
 
    setTimeout(()=>{ 
 
    
 
     this.setProperty('_isLoggedIn',true) 
 
    
 
    },1500) 
 

 
    } 
 

 
    isLoggedIn(){ 
 

 
    return this._isLoggedIn === true 
 

 
    } 
 
    
 
    setProperty(propertyName,value){ 
 

 
    this[propertyName] = value 
 
    // update func passed from app 
 
    // updates app state 
 
    this.onChange(this) 
 
    } 
 

 
} 
 

 
ReactDOM.render(<App />,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>