首页 > 解决方案 > 未处理的拒绝(SyntaxError):意外的令牌 < 在 JSON 中的位置 0 React

问题描述

每当我尝试使用来自不同组件的全局变量时,我不断收到“未处理的拒绝(SyntaxError):位置 0 处的 JSON 中的意外令牌 <”错误,在这种情况下,当我在 Random 中使用来自 Brewery.js 的全局变量时。 js

Brewery.js

  componentDidMount() {
    window.url = "https://api.openbrewerydb.org/breweries";
    fetch(window.url)
      .then(response => response.json())
      .then((data) => {
        this.setState({
          breweries: data,
        })
      })
  }

随机.js

  componentDidMount() {
    fetch(window.url)
      .then(response => response.json())
      .then((data) => {
        this.setState({
          breweries: data,
        })
      })
  }

标签: javascriptreactjs

解决方案


您说过第一个块 (Brewery.js) 有效,但第二个 (Random.js) 无效。

在另一个组件中创建全局变量componentDidMount并依赖它肯定是不好的做法。显然,发生的情况是第二个组件在第一个之前安装,所以window.urlundefined,所以你最终请求"undefined"而不是正确的 URL。

首先,不要重复自己。相反,有一个获取啤酒厂的函数,并重用它:

function getBreweries() {
  return fetch(window.url)
    .then(response => {
        if (!response.ok) {
            throw new Error("HTTP error " + response.status);
        });
        return response.json();
    });
}

你甚至可以让它处理设置状态:

function loadBreweriesIntoState() {
  return fetch(window.url)
    .then(response => {
        if (!response.ok) {
            throw new Error("HTTP error " + response.status);
        });
        return response.json();
    })
    .then(breweries => {
        component.setState({breweries});
    })
    .catch(error => {
        component.setState({error: "Error loading the list of breweries."});
    });
}

然后,在两个组件(Random.js 和 Brewery.js)中,使用该函数而不是重复逻辑。

这使我们想到:您如何使该功能对两个组件都可用?

两个答案:

  1. 如果您正在使用模块(我强烈推荐),请将其放入他们都使用的模块中:

    loadBreweriesIntoState.js

    export default function loadBreweriesIntoState() {
        // ...
    }
    

    Brewery.js

    import loadBreweriesIntoState from "./loadBreweriesIntoState.js";
    
    // ...
    
        componentDidMount() {
            loadBreweriesIntoState(this);
        }
    

    Random.js

    import loadBreweriesIntoState from "./loadBreweriesIntoState.js";
    
    // ...
    
        componentDidMount() {
            loadBreweriesIntoState(this);
        }
    
  2. 如果您不使用模块,请将其放入您在两个组件脚本(开发中)之前包含的脚本中,并设置为在它们之前包含在您的包中(用于生产)。

如果您也想将逻辑保留在组件中,那么这两个选项也适用:只需url在某种Config.js(或它创建的全局)中进行导出。


推荐阅读