【问题标题】:Property in state becomes undefined within action creators状态中的属性在动作创建者中变得未定义
【发布时间】:2020-04-16 02:42:06
【问题描述】:

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

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 请求时,它也不能很好地工作,所以我想一定有更好的方法来访问状态。我真的很感激能帮我解决这个问题。

【问题讨论】:

  • 您可以尝试先将 getState().auth.user.id 添加到变量中吗:const userId = getState().auth.user.id console.log(userId) => 从控制台检查 userId 是否正确,然后在 axios 中使用它。获取:get(/api/users/${userId}/flowers)
  • 我试过了,但我得到了相同的结果。当我登录后,它可以工作(至少最初是这样)。它加载正确的用户,控制台记录正确的 ID。但是当我刷新页面时,它会崩溃,并出现相同的错误,即 Id 为空。

标签: reactjs redux react-redux


【解决方案1】:

当您登录时,您应该设置本地存储来保存用户信息,如下所示:

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。如果用户登录,有令牌,所以应用程序不会崩溃

【讨论】:

    猜你喜欢
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2017-08-26
    • 2018-11-23
    • 2019-09-26
    • 1970-01-01
    相关资源
    最近更新 更多