NodeJS 刷新页面后无法读取未定义(阅读“includes”)错误的属性

ki1q1bka  于 2022-12-18  发布在  Node.js
关注(0)|答案(2)|浏览(297)

我正在尝试使用reactjs制作一个Web应用程序,但遇到了这个错误......我正在尝试在产品卡上添加一个“喜欢”按钮,如果用户喜欢该产品,“喜欢”按钮将被填充。当我已经在localhost上的页面上并更改代码时(立即更新,因为我正在使用Nodemon)更改显示出来,工作正常。但是,一旦我刷新页面,或者如果我尝试在更改存在时再次打开页面,我会得到这个错误:

TypeError: Cannot read properties of undefined (reading 'includes')

下面是我的代码:

function Product(props) {
  const { product } = props;

  const { state } = useContext(Store);
  const { userInfo } = state;

  const [{ loading, user }, dispatch] = useReducer(reducer, {
    loading: false,
    user: [],
  });

  useEffect(() => {
    const fetchUser = async () => {
      dispatch({type: 'FETCHUSER_REQUEST'});
      try {
        const user = await axios.get(
          '/api/users/profile', {
            headers: {Authorization: `Bearer ${userInfo.token}`},
          }
        );
        dispatch({type: 'FETCHUSER_SUCCESS', payload: user.data});
      } catch(err) {
        dispatch({type: 'FETCHUSER_FAIL'});
        toast.error(getError(err));
      }
    }
    fetchUser();
  }, []);

  const [favourites, setFavourites] = useState([]);

  const likesHandler = async(e) => {
    e.preventDefault();
    favourites.push(product._id);
    setFavourites(favourites => [...favourites, product._id]);
      const { data } = await axios.put(
        '/api/users/likes',
        { favourites },
        {
          headers: {Authorization: `Bearer ${userInfo.token}`},
        }
      );
  };

  console.log(user);
  console.log(user.favourites);

  return (
    <Card styles="1px solid grey">
      <Link to={`/product/${product.slug}`}>
        <img src={product.image} className="card-img-top" alt={product.name} />
      </Link>
      <Card.Body>
        <Link to={`/product/${product.slug}`}>
          <Card.Title>{product.name}</Card.Title>
        </Link>
        <Rating rating={product.rating} numReviews={product.numReviews} />
        <Card.Text>${product.price}</Card.Text>
        {product.stock === 0 ? (
          <Button variant="light" disabled>
            Out of stock
          </Button>
        ) : (
          <Button onClick={() => addToCartHandler(product)}>Add to cart</Button>
        )}
      </Card.Body>

      {user.favourites.includes(product._id) ? (
        <i class="fas fa-heart fa-lg card-icon-btm"></i>
      ) : (
        <span onClick={likesHandler}>
          <i class="far fa-heart fa-lg card-icon-btm"></i>
        </span>
      )}

    </Card>
  );
}
export default Product;

我的API代码:

userRouter.get(
  '/profile',
  isAuth,
  expressAsyncHandler(async (req, res) => {
    const user = await User.findById(req.user._id);
    res.send(user);
  })
);

userRouter.put(
  '/likes',
  isAuth,
  expressAsyncHandler(async(req, res) => {
    const user = await User.findById(req.user._id);

    if (user) {
      user.favourites.push(req.body.favourites[0])
    }
    await user.save();
  })
);


刷新后,console.log(user)将返回空,user.favourites将返回undefined。我知道这可能是我的用户数据填充方式的问题,但我不知道是什么问题...我在代码开始时填充用户。如果有人知道问题可能是什么,将非常感激!

nfs0ujit

nfs0ujit1#

我相信这个错误的发生是因为如果你加载你的页面形式“新鲜”开始你有空的用户数组,直到它从API获取-你必须检查它是否有你想要获得的属性。
在您的情况下,您可以通过在检查您查找时可能不存在的对象之前添加问号来避免此错误。

{user?.favourites?.includes(product._id) ? (
    <i class="fas fa-heart fa-lg card-icon-btm"></i>
  ) : (
    <span onClick={likesHandler}>
      <i class="far fa-heart fa-lg card-icon-btm"></i>
    </span>
  )}

如果未定义代码填充,则只需返回false并返回此指令的“else”块。

mjqavswn

mjqavswn2#

您描述的部分问题可以通过使用可选的链接(?.)运算符来解决。?.includes(product._id)而不是?.includes(product._id)。至少你可以不再得到这样的错误。
在我的例子中,我在我的javascript项目中遇到了同样的错误,因为我使用.includes();来检查一个有时是“未定义”的变量,我使用?.includes();解决了这个问题。
阅读完这篇文章后我就明白了,文章说:
可选的链接(?.)运算符也可以用来避免错误,因为如果引用等于undefined或null,它会短路返回undefined。

相关问题