已部署的 React 应用程序在活动和登录上返回“未定义”不是有效的 JSON 错误

问题描述 投票:0回答:1

标题:错误“未定义”在 React 应用程序的生产中不是有效的 JSON

我最近在 https://fundingfriends-frontend.onrender.com/ 部署了我的 React 应用程序。但是,当我点击一个广告系列(例如第一个广告系列)时,我遇到以下错误:

react-dom.production.min.js:188 
SyntaxError: "undefined" is not valid JSON
    at JSON.parse (<anonymous>)
    at useToken.js:6:32
    ...

同样,当我尝试登录时,我收到相同的错误:

react-dom.production.min.js:188 
SyntaxError: "undefined" is not valid JSON
    at JSON.parse (<anonymous>)
    at useToken.js:6:32
    ...

这是我第一次在 Render 上部署,我的后端似乎工作正常。我可以毫无问题地访问以下 API 端点:

相关代码

useToken.js:

import { useState } from "react";

export default function useToken() {
    function getToken() {
        const tokenString = localStorage.getItem('accessToken');
        const userToken = JSON.parse(tokenString);
        if(userToken) {
            console.log("Found userToken");
            return userToken;
        } else {
            return null;
        }
    }

    const [token, setToken] = useState(getToken());

    function saveToken(userToken) {
        localStorage.setItem('accessToken', JSON.stringify(userToken));
        setToken(userToken);
    }

    return {
        token, setToken: saveToken
    }
}

发生错误的组件(CampaignDetails.js):

import { useState, useEffect, useContext } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';
import useToken from 'src/hooks/useToken';
import { APIURLContext } from 'src/contexts/APIURLContext';
import 'src/pages/CampaignDetails/CampaignDetails.css';

function CampaignDetail() {
  const { id } = useParams();
  const [campaign, setCampaign] = useState({ campaign: {}, donations: [] });
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const { token } = useToken();
  const apiURL = useContext(APIURLContext);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const campaignResponse = await axios.get(`${apiURL}/campaigns/${id}`);
        setCampaign(campaignResponse.data);
      } catch (error) {
        console.error("Error fetching campaign data:", error);
      }
    };

    fetchData();
  }, [id, apiURL]);

  useEffect(() => {
    setIsLoggedIn(!!token);
  }, [token]);

  const totalDonations = campaign.donations.reduce((total, donation) => total + donation.amount, 0);
  const progress = (totalDonations / campaign.campaign.goal) * 100;

  const handleEmailShare = () => {
    const subject = 'Check out this donation campaign!';
    const body = `Hi there,\n\nI found this donation campaign that I think you might be interested in. \n\nHere's the link: ${window.location.href}\n\nBest regards,\n[Your Name]`;
    window.location.href = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
  };

  const handleSmsShare = () => {
    const message = `Check out this donation campaign: ${window.location.href}`;
    window.location.href = `sms:?body=${encodeURIComponent(message)}`;
  };

  return (
    <div className="details-page-container">
      <div className="row">
        <div className="col-md-6 d-flex flex-column justify-content-between">
          <div>
            <h1>{campaign.campaign.name}</h1>
            <p>{campaign.campaign.description}</p>
            <p>
              <span className="donation-amount">${totalDonations} </span>
              raised of ${campaign.campaign.goal}
            </p>
            <p>{campaign.donations.length} donations</p>
            <p className={`funded-status ${progress >= 100 ? 'funded' : ''}`}>
              {`This campaign is ${progress.toFixed(2)}% funded!`}
              <div className="progress">
                <div className="progress-bar" role="progressbar" style={{ width: `${(totalDonations / campaign.campaign.goal) * 100}%` }} aria-valuenow={(totalDonations / campaign.campaign.goal) * 100} aria-valuemin="0" aria-valuemax="100"></div>
              </div>
            </p>
          </div>
          <div className="mt-3">
            {isLoggedIn && (
              <form action={`${apiURL}/donations/create_checkout`} method='POST'>
                <input type='hidden' name='campaign_id' value={campaign.campaign._id} />
                <input type='hidden' name='campaign_name' value={campaign.campaign.name} />
                <input
                  type='number'
                  id='donation_amount'
                  name='donation_amount'
                  min='0'
                  step='0.01'
                  defaultValue='30.00'
                />
                {token && <input type='hidden' name='token' value={token} />}
                <button type='submit' className="donate-button">Donate</button>
              </form>
            )}
            <button className="share-button" onClick={handleEmailShare}>Share via Email</button>
            <button className="share-button" onClick={handleSmsShare}>Share via SMS</button>
          </div>
        </div>
      </div>
      <div className="row mt-5">
        <div className="col">
          <h3>Donations</h3>
          <div className="donations-container">
            {campaign.donations.map((donation, index) => (
              <div key={index} className="donation-card">
                <p><strong>Amount:</strong> ${donation.amount}</p>
                {donation.payment_id && <p><strong>Payment ID:</strong> {donation.payment_id}</p>}
                <p><strong>Message:</strong> {donation.message}</p>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export default CampaignDetail;

问题

为什么我在生产中收到“undefined is not valid JSON”错误,但在开发中却没有?我可以采取哪些步骤来有效地调试此问题?

javascript reactjs json deployment axios
1个回答
0
投票
当您调用

tokenString

 时,
JSON.parse(tokenString)
是未定义的,因为本地存储中没有任何内容可以使用
localStorage.getItem()
。在尝试解析它之前检查
tokenString
并查看它是否有价值。

const tokenString = localStorage.getItem('accessToken');
if(!tokenString) return null
const userToken = JSON.parse(tokenString);
© www.soinside.com 2019 - 2024. All rights reserved.