【问题标题】:React/Redux - Dispatch method - returning errorReact/Redux - 调度方法 - 返回错误
【发布时间】:2019-03-14 01:32:08
【问题描述】:

我目前正在尝试在页面上添加和删除我的项目,但它返回了一个错误。

Unhandled rejection (TypeError): Cannot read property data of undefined 在以下代码中都指向.catch

export const addItem = (item) => (dispatch, 
getState) => {
 axios
  .post('/api/items', item, tokenConfig(getState))
  .then(res => dispatch({
    type: ADD_ITEM,
    payload: res.data
}))
  .catch(err => dispatch(returnErrors(err.response.data, err.response.status))
 );
};

export const deleteItem = (id) => (dispatch, getState) => {
axios
 .delete(`/api/items/${id}`, tokenConfig(getState))
 .then(res => dispatch({
    type: DELETE_ITEM,
    payload: id
}))
 .catch(err => dispatch(returnErrors(err.response.data, err.response.status))
 );
};

/////////////////////////////////////// //

上面引用的 returnErrors 方法来自另一个文件:

import { GET_ERRORS, CLEAR_ERRORS } from './types';

// RETURN ERRORS

export const returnErrors = (msg, status, id = null) => {
 return {
   type: GET_ERRORS,
payload: { msg, status, id }
 };
};


// CLEAR ERRORS

export const clearErrors = () => {
 return {
   type: CLEAR_ERRORS
 };
};

我在dispatch(returnErrors(err.response.data, err.response.data)); 的正上方放置了一个console.log(err.response) 和一个console.log(err.response.data),并为第一个返回undefineduncaught (in promise) cannot read property of undefined

有人告诉我

This essentially means your error object doesn't have correct data. Please look into the error object returned. It could be an issue with items/user api, it should return correct error object.

items api 路由

router.post('/', auth, (req, res) => {
 const newItem = new Item({
   name: req.body.name
 })

   newItem.save().then(item => res.json(item));
});

// DELETE api/items/:id
// Delete an item
// Private

router.delete('/:id', auth, (req, res) => {
  Item.findById(req.params.id)
   .then(item => item.remove().then(() => res.json({ deleted: true 
})))
   .catch(err => res.status(404).json({ deleted: false }));
})

不确定数据未定义的位置。有人发现有什么遗漏吗?

您可以在此处查看 chrome 开发工具网络选项卡返回的内容:

https://imgur.com/D5OGLpf

authActions

// Check token & Load User
// Want to check routes/auth.js for user by id that's included with token
// Going to use asynchronous request, use dispatch
export const loadUser = () => (dispatch, getState) => {

// User loading
 dispatch({ type: USER_LOADING });


// Fetch user
 axios.get('/api/auth/user', tokenConfig(getState))
  .then(res => dispatch({
     type: USER_LOADED,
  payload: res.data
 }))
  .catch(err => {
    dispatch(returnErrors(err.response.data, err.response.status));
  dispatch({
     type: AUTH_ERROR
   });
  });
 };

// Register User

export const register = ({ name, email, password }) => dispatch => {
// Headers
 const config = {
   headers: {
    'Content-Type': 'application/json'
  }
}

// Request body

const body = JSON.stringify({ name, email, password });

axios.post('/api/users', body, config)
 .then(res => dispatch({
     type: REGISTER_SUCCESS,
  payload: res.data
 }))
 .catch(err => {
  dispatch(returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL'));
  dispatch({
  type: REGISTER_FAIL
  });
 });
};

// LogIn

export const login = ({ email, password }) => dispatch => {
// Headers
const config = {
  headers: {
    'Content-Type': 'application/json'
   }
 }

 // Request body

 const body = JSON.stringify({ email, password });

 axios.post('/api/auth', body, config)
  .then(res => dispatch({
     type: LOGIN_SUCCESS,
  payload: res.data
 }))
  .catch(err => {
  dispatch(returnErrors(err.response.data, err.response.status, 
 'LOGIN_FAIL'));
  dispatch({
    type: LOGIN_FAIL
  });
 });
};


// LogOut

export const logout = () => {
  return {
   type: LOGOUT_SUCCESS
 };
};


// Setup config/headers and Token

export const tokenConfig = (getState) => {

// Get token from localstorage
const token = getState().auth.token;

// Headers
const config = {
   headers: {
    "Content-type": "application/json"
  }
 }

 // Check if token exists, add to Headers
  if(token) {
    config.headers['x-auth=token'] = token;
  }

  return config;
 }

【问题讨论】:

  • 欣赏
  • 显示准确的服务器响应(Chrome DevTools -> Network -> etc)
  • 我已经做到了,有没有我可以分享截图
  • 问题是我在您的屏幕截图中没有看到对/api/items 的任何请求。 Network中有3个常见请求(js + map + svg),没有xhr。另一方面,控制台为某些/api/items 显示401。如果您确定/api/items 正在发送,您应该可以在“网络”选项卡中打开它。

标签: javascript reactjs redux promise axios


【解决方案1】:

基于您的图像https://imgur.com/D5OGLpf,您对axios.delete('/api/items/${id} 的请求不会到达路由/api/items/:id

我为什么这么说?

响应状态为 401 (https://imgur.com/D5OGLpf),表示未授权。路由router.delete('/:id' 的端点可能受到身份验证中间件或类似的东西的保护。

为了解决它,

第一

您需要使用为 api 设置的方式发出经过身份验证的请求,无论是基本身份验证、oauth[2] 还是您自定义的身份验证。

那么

在发送dispatch(returnErrors...之前,需要检查数据是否存在。

axios
 .delete(`/api/items/${id}`, tokenConfig(getState))
 .then(res => dispatch({
    type: DELETE_ITEM,
    payload: id
 }))
 .catch(err => {
   if(error.status === 404) {
      // here, you are sure that error.response.data exists
      dispatch(returnErrors(err.response.data, err.response.status)   
   }
   else {
      // do something else to handle the error
   }

 })

**请记住,**捕获的错误可以是从错误状态 400、500...到.then(...) 中未捕获的错误。

【讨论】:

  • hm 好的,这是我第一次使用react/redux,设置需要一段时间,请看一下添加的代码
  • @mph85 该错误与redux本身无关。完全理解我在上面First部分的回答将帮助您解决问题。
【解决方案2】:

删除项目的内部承诺仍处于待处理状态,并且正如您所指出的,不会返回任何响应。

了解正在发生的事情。

Item.findById(req.params.id)
   .then(item => item.remove().then(() => res.json({ deleted: true 
})))
   .catch(err => res.status(404).json({ deleted: false }));
})

可以简化为

P.then(p => Q)

PQ 是 Promise 对象。

P 完成时,它返回Q 并且Q 继续保持在等待它被解决的挂起状态。

您可以通过扁平化then 链来解析Q,以便在删除操作完成时进行处理。

Item.findById(req.params.id)
   .then(item => item.remove())
   .then(() => res.json({ deleted: true }))
   .catch(err => res.status(404).json({ deleted: false }));

【讨论】:

  • 感谢您的回复。我刚刚修改它,它仍然给我同样的错误
  • 这很好奇。您是否偶然使用了 mongoose 库?另外,修改的时候需要重启服务器。
  • 我正在使用猫鼬,但也安装了 nodemon,因此它会在任何更改时自动重新启动服务器
  • 使用猫鼬中的Model.findByIdAndRemove 方法怎么样?
  • 能否确认请求处理程序已执行?请求可能无法通过 auth 中间件处理
猜你喜欢
  • 2018-05-21
  • 2017-12-27
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多