状态创建者在动作创建者中无法定义状态

时间:2019-12-25 12:46:07

标签: reactjs redux react-redux

我正在制作一个应用程序,不同的用户可以在其中添加自己的植物/花朵。 鲜花清单包含用户鲜花,并在安装时加载这些项目。

class flowerList extends Component {
componentDidMount() {
    this.props.getFlowers();
}

要将正确的GET请求发送到后端,我需要具有当前登录的用户ID。 这就是所谓的动作创建者的样子:

export const getFlowers = () => (dispatch, getState) => {
dispatch(setFlowersLoading());
axios
    .get(`/api/users/${getState().auth.user.id}/flowers`)
    .then((res) =>
        dispatch({
            type    : GET_FLOWERS,
            payload : res.data
        })
    )
    .catch((err) => dispatch(returnErrors(err.response.data, err.response.status)));
};

但是,这不能很好地工作。它仅在直接来自登录时有效。如果刷新页面,则应用程序崩溃,并显示错误消息“ TypeError:无法读取null的属性'id'”。当以类似的方式编写POST请求时,它也不能很好地工作,因此我想必须有一种更好的方式来访问状态。我真的很感激能使它生效。

1 个答案:

答案 0 :(得分:0)

登录时,应设置本地存储以保留用户信息,如下所示:

const setAuthorizationHeader = token => {
  const Token = `Bearer ${token}`;
  localStorage.setItem("Token", Token);
  axios.defaults.headers.common["Authorization"] = Token;
};

您可以将其添加到then()之后的用户登录操作中,当登录成功时,下面是一个示例,假设您在后端处理令牌,因此成功登录后,它将发送令牌带有响应(res.data):

export const loginUser = (userData) => dispatch => {
  axios
    .post("http://localhost:5000/api/users/login", userData)
    .then(res => {
      setAuthorizationHeader(res.data.token);    
    })
    .catch(err => {
      dispatch({
        type: SET_ERRORS,
        payload: err.response
      });
    });
};

然后,将它们放入您的app.js:

const token = localStorage.Token;
if (token) {
  const decodedToken = jwtDecode(token);
  if (decodedToken.exp * 1000 < Date.now()) {
    store.dispatch(logoutUser());
    window.location.href = "/login";
  } else {
    store.dispatch({ type: SET_AUTHENTICATED_USER });
    axios.defaults.headers.common["Authorization"] = token;
    store.dispatch(getUserData(decodedToken));
  }
}

这里,我使用jwtDecode是因为我正在使用JWT加密用户的信息并将其存储到localStorage,这些代码用于在刷新页面后在localStorage中查找Token。如果用户登录,则有令牌,因此应用程序不会崩溃