首页 > 解决方案 > 在三元检查对象是否未定义之前,react 会为未定义的对象抛出错误

问题描述

我有可怕的无法读取未定义的状态。我在前端使用 React,后端使用 mongodb、express 和 nodejs。

我正在使用功能组件。"bag" 道具有 bag.disccollection 和 bag.image.data。

bag.disccollection 是一个对象数组,bag.image.data 包含一个存储在我的 mongodb 数据库中的 bson 图像数据数组。从邮递员的 mongodb 获取这些数据允许我查看图像,所以我认为图像正在工作。

正如您在下面看到的,我使用三元运算符来显示 bag.discollection,因为如果我不检查“bag”是否存在,我将得到 undefined/null 错误。但是,我对 bag.image.data 使用相同的逻辑,并且收到如下所示的错误。编辑:Github repo https://github.com/2stash/discgolf.git

const DiscBag = ({
  getBag,
  auth: { user },
  bag: { bag, loading, editdisc },
}) => {
  useEffect(() => {
    getBag();
  }, [getBag]);

  return loading && bag === null ? (
    <Spinner />
  ) : (
    <Fragment>
      <h1 className='large text-primary'>Dashboard</h1>
      <p className='lead'>
        <i className='fas fa-user'></i> Welcome {user && user.name}
      </p>
      {!editdisc ? <AddDisc /> : <EditDisc />}

      {bag !== null ? (
        <DisplayDiscs discList={bag.disccollection} />
      ) : (
        <DisplayEmptyBag />
      )}
      
      {bag !== null && bag.image !== null ? <Image data={bag.image.data}/> : <p>Hi</p>}
 
    </Fragment>
  );

这是我目前收到的错误消息。

Unhandled Rejection (TypeError): Cannot read property 'statusText' of undefined
(anonymous function)
C:/Users/Daniel/projects/discgolf/client/src/actions/bag.js:24
  21 |   } catch (err) {
  22 |     dispatch({
  23 |       type: BAG_ERROR,
> 24 |       payload: { msg: err.response.statusText, status: err.response.status },
  25 |     });
  26 |   }
  27 | }

这是我的图像组件。我正在努力将 bson 转换回要显示的图像。如果我注释掉 "let imageStr..." ,console.log 将工作并显示数据。

const Image = ({ data }) => {
  
  const imageData = data
  let imageStr = arrayBufferToBase64(imageData)
  console.log(imageData)

  const arrayBufferToBase64 = (buffer) => {
    let binary = '';
    let bytes = [].slice.call(new Uint8Array(buffer));

    bytes.forEach(b => binary += String.fromCharCode(b));

    return window.btoa(binary);
  }
  return <p>Hi</p>
    
};

Image.propTypes = {
  data: PropTypes.array.isRequired,
};

export default Image;

关于如何调试的任何想法。我真的很困惑,因为我正在使用三元运算符并且它正在查找我的其他数据,并且数据似乎正确到达。另外我不知道为什么我的 redux 操作会引发错误。(如果有人对 mern 堆栈的图像处理有更好的解决方案,请告诉我)

编辑以添加 redux 操作代码:还链接到 github 以获取不包含此图像功能的稳定版本

import axios from "axios";
import { setAlert } from "./alert";

import { 
  GET_BAG,
  BAG_ERROR,
  DELETE_DISC,
  SET_DISC,
  UPDATE_DISC,
} from "./types";

// Get current users bag
export const getBag = () => async (dispatch) => {
  try {
    const res = await axios.get("/api/bag/me");
    // console.log(res.data)
    dispatch({
      type: GET_BAG,
      payload: res.data,
    });
  } catch (err) {
    dispatch({
      type: BAG_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status },
    });
  }
}

更新:我进入 bag.js 的 redux 操作文件并删除了错误有效负载消息,我收到以下消息

ReferenceError: Cannot access 'arrayBufferToBase64' before initialization
Image
C:/Users/Daniel/projects/discgolf/client/src/components/discbag-copy/Image.js:10
   7 | const Image = ({ data }) => {
   8 |   
   9 |   const imageData = data
> 10 |  arrayBufferToBase64(imageData)
  11 |   console.log(imageData)
  12 | 
  13 |   const arrayBufferToBase64 = (buffer) => {

标签: javascriptreactjsmulter

解决方案


您已检查 bag.image 的空值。您还应该检查它是否未定义。您可以检查虚假值,而不是检查特定值 (null)。

例如,

!!bag && !!bag.image

如果 bag 变量为 null,!!bag 将返回 false。如果它有一个真值 !!bag 将返回真。通过此检查,如果 bag 和 bag.image 为 null 或未定义,则两者都将得到处理。


推荐阅读