反应,终极版/反应路由器:如何在链接

问题描述:

改变状态在网页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

终极版是所有关于一致,干净利落地跟踪您的应用程序的状态,独立的哪些组件正在使用的状态。所以,故障状态保持不变并不奇怪,除非你明确地清除它。

因此,接下来的问题是,在什么情况下,你要清除故障状态? (在什么情况下你想忘记页面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组件挂载时也初始化),它被清除,所以我不认为它可能导致他的问题。 –