2016-08-19 128 views
1

改變狀態在網頁A,我有導致B頁一個反應路由器<Link>。在頁B,我有一個按鈕,試圖在服務器上執行某些操作,並且導致頁(成功)或停留在頁B(失敗)。在最後一種情況下,頁面上會顯示一條消息以顯示錯誤。反應,終極版/反應路由器:如何在鏈接

時我已經在B頁錯誤信息,如果我使用瀏覽器的後退按鈕返回上網頁A然後再次單擊<Link>B頁,該消息仍然在這裏。

所以看起來狀態在使用<Link>時沒有重置,我想知道改變<Link>狀態的好方法是什麼?


編輯: 使其更清晰,在網頁A你有一個<Link>網頁B。在頁面B你有一個按鈕來提交你的登錄信息(登錄名和密碼)。

當你點擊,一個動作做的請求到服務器:

function authRequest() { 
    return { 
    type: actionTypes.AUTH_REQUEST 
    }; 
} 

function authReceive(authToken) { 
    return { 
    type: actionTypes.AUTH_RECEIVE, 
    authToken 
    }; 
} 

function authError(errors) { 
    return { 
    type: actionTypes.AUTH_ERROR, 
    errors 
    }; 
} 

export function fetchLogin(email, password) { 
    return function (dispatch) { 
    dispatch(authRequest()); 
    const urlApi = `//${AUTH_BACKEND_HOST}:${AUTH_BACKEND_PORT}/${AUTH_BACKEND_URL.login}` 
    fetch(urlApi, { 
     method: 'POST', 
     headers: { 
     'Accept': 'application/json', 
     'content-type': 'application/json' 
     }, 
     body: JSON.stringify({ 
     email, 
     password 
     }) 
    }) 
    .then((response) => { 
     if(response.ok) { 
     response.json().then(function(json) { 
      dispatch(authReceive(json.key)); 
      dispatch(push('/')); 
     }); 
     } else { 
     response.json().then(function(json) { 
      dispatch(authError(JSON.stringify(json))); 
     }); 
     } 
    }) 
    .catch(function(ex) { 
     console.log(ex); 
    }); 
    }; 
} 

...如果它失敗,減速的狀態添加錯誤消息:

const initialState = { 
    authToken: '', 
    isFetching: false, 
    errors: '' 
} 

export default function (state=initialState, action) { 
    switch (action.type) { 
    case actionType.AUTH_REQUEST: 
     return { 
     ...state, 
     isFetching: true, 
     errors: '' 
     }; 
    case actionType.AUTH_RECEIVE: 
     return authLogin(state, action); 
    case actionType.AUTH_ERROR: 
     return { 
     ...state, 
     errors: (JSON.parse(action.errors)) 
     }; 
    } 
    return state; 
} 

function authLogin(state, action) { 
    const { authToken } = action; 
    return { 
    ...state, 
    isFetching: false, 
    errors: '', 
    authToken 
    }; 
} 

...最後,發言人有一個渲染方法,其中<p>顯示錯誤,如果它處於該狀態:

render() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <label>Email <input ref="email" /></label> 
     <label>Password <input ref="password" type="password" /></label><br /> 
     <p className="error">{this.props.errors.non_field_errors}</p> 
     <button type="submit">Login</button> 
     </form> 
    ) 
    } 

因此,正如我說的,如果它顯示的錯誤,然後我回去就網頁A然後網頁B再次通過點擊鏈接,該消息仍然存在。

謝謝。

+0

如果狀態未被重置,則表示沒有調用ComponentB的'componentWillMount'。包括你的路由配置,它會給出更好的想法 – Deadfish

+0

你是對的,在我正在工作的這個應用程序中沒有* componentSomething *這樣的函數。我在一些例子中看到了他們,但沒有一個用在這個應用程序中,我仍然可以設法註冊用戶,然後在主頁面上進行連接和導航。 – Destal

回答

2

終極版是所有關於一致,乾淨利落地跟蹤您的應用程序的狀態,獨立的哪些組件正在使用的狀態。所以,故障狀態保持不變並不奇怪,除非你明確地清除它。

因此,接下來的問題是,在什麼情況下,你要清除故障狀態? (在什麼情況下你想忘記頁面B的操作失敗的事實?)

  1. 當從A到B跟隨<Link>?你可以用<Link>'s onClick這樣做,但它看起來過於具體。 (如果用戶以某種方式得到B,又怎麼辦?爲什麼A的鏈接不得不關心B的故障狀態?)
  2. 當B掛載? (換句話說,「每次輸入B時,都將其視爲空白石板。」)要實現此目的,請使用componentWillMount
  3. 當B卸載? (換句話說,「每次我離開B,扔掉B中任何操作的狀態」。)要實現這一點,請使用componentWillUnmount

我猜測選項2或3最適合您的設計。那麼你會從componentWillMountcomponentWillUnmount發出適當的動作,並且該動作的縮減器將清除任何故障狀態。

+0

謝謝我會嘗試,我看到一些函數,如* componentSomething *存在,但我沒有使用這個。所以,是的,我希望B每次進入時都是空白的。 – Destal

+0

關於(3),我不認爲我們需要明確清除狀態後,卸載,我們的反應是這樣的 – Deadfish

+0

@Deadfish-我應該已經被確認的術語。如果通過「狀態」,他意味着存儲在Redux存儲中的應用程序狀態(這是我的假設),它只要Redux存儲(可能是整個應用程序)就存在。如果他的意思是頁面B的React組件狀態,那麼你是對的,當頁面B的組件卸載時(並且在頁面B組件掛載時也初始化),它被清除,所以我不認爲它可能導致他的問題。 –