react-redux / react-router:如何在链接

时间:2016-08-19 14:23:32

标签: reactjs react-router react-redux

第A页上,我有一个react-router <Link>,指向第B页。在第B页上,我有一个按钮,尝试在服务器上执行某些操作,并导致页面C (成功)或保留在页面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);
    });
  };
}

...如果失败, reducer 会在状态中添加错误消息:

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 ,点击链接,消息仍然存在。

谢谢。

1 个答案:

答案 0 :(得分:3)

Redux是一致的,干净地跟踪应用程序的状态,与使用该状态的组件无关。因此,失败状态保持不变并不奇怪,除非您专门清除它。

接下来的问题是,您希望在什么情况下清除故障状态? (在什么情况下你想忘记页面B操作失败的事实?)

  1. 从A到B跟随<Link>时?您可以使用<Link>'s onClick执行此操作,但它似乎过于具体。 (如果用户以其他方式到达B怎么办?为什么A的Link必须关心B的失败状态?)
  2. 当B安装? (换句话说,“每次我输入B时,都将其视为空白名单。”)要实现此目的,请使用componentWillMount
  3. 当B卸下? (换句话说,“每次离开B时,都要丢弃B中任何操作的状态。”)为了实现这一点,请使用componentWillUnmount
  4. 我猜测选项2或3最适合您的设计。因此,您将从componentWillMountcomponentWillUnmount发送适当的操作,该操作的reducer将清除任何失败状态。