简体   繁体   English

获取未捕获的 RangeError:React 中超出了最大调用堆栈大小

[英]Getting Uncaught RangeError: Maximum call stack size exceeded in React

I'm a beginner with React and I have been coding a project for one of the courses in uni.我是 React 的初学者,我一直在为 uni 中的一门课程编写一个项目。 However, I have been now struggling for quite some time with following error: Uncaught RangeError: Maximum call stack size exceeded.但是,我现在已经为以下错误苦苦挣扎了一段时间:Uncaught RangeError: Maximum call stack size exceeded。 I have tried to find a solution with no luck.我试图找到一个没有运气的解决方案。

Here is my code for the React component that causes the error:这是导致错误的 React 组件的代码:

` `

import { Container } from "react-bootstrap"
import { useParams } from "react-router"
import apiService from "../services/apiService"
import { useEffect, useState } from "react"
import Spinner from 'react-bootstrap/Spinner';

const GOOGLE_API_KEY = process.env.REACT_APP_GOOGLE_API_KEY

export const TreeProfile = (props) => {
  const [tree, setTree] = useState({})
  const [fetching, setFetching] = useState(true)
  const [zoom, setZoom] = useState("12")
  const [location, setLocation] = useState({latitude: "", longitude: ""})

  let { id } = useParams()

  const handleZoomChange2 = (event) => {
    console.log(event.target.value)
    setZoom(event.target.value)
  }

  console.log("Called TreeProfile")

  useEffect(() => {
    console.log("id", id)
    apiService.getOne(id).then(t => {
      console.log("data", t)
      setTree(t)
      setLocation({latitude: t.location.latitude, longitude: t.location.longitude})
      setFetching(false)
    })
  }, [])

  return (
    <Container className="treeprofile-page">
      {
        fetching === false ?
        <img style={{height: '200px', width: '300px'}} src={`data:image/${tree.image.contentType};base64,${btoa(String.fromCharCode(...new Uint8Array(tree.image.data.data)))}`} alt='' />
        :
        <Spinner animation="border" variant="primary" />
      }
      
      <h1>{tree.name}</h1>
      {
        fetching === false ?
        <h3>Planted on {new Date(tree.createdAt).toDateString()}</h3>
        :
        null
      }
      <h3>Planted by {tree.user}</h3>

      {
        fetching === false ?
        <div>
        <img src={`https://maps.googleapis.com/maps/api/staticmap?center=${location.latitude},${location.longitude}&format=gif&zoom=${zoom}&size=300x200&markers=color:red%7C${location.latitude},${location.longitude}&key=${GOOGLE_API_KEY}`} alt='' />
        </div>
        :
        null
      }
      <div>
        <input className="m-3" type="range" min="1" max="16" value={zoom} onChange={handleZoomChange2} />
      </div>

      <button type="button" className="btn btn-primary" >Add update</button>
      
    </Container>
  )
}

` `

The error happens every time I try to update the zoom level by sliding the slider, which calls handleZoomChange2 function that sets the state. I have other component in different route with the same functionality and it works fine.每次我尝试通过滑动 slider 来更新缩放级别时都会发生错误,它调用设置 state 的 handleZoomChange2 function。我在不同的路径中有其他组件具有相同的功能并且它工作正常。 However, this one for some reason causes the error constantly.但是,由于某种原因,这个错误不断地导致错误。

The apiService fetches the data with axios from the backend, which in turn fetches the data from MongoDB. apiService 从后端获取 axios 的数据,后端又从 MongoDB 获取数据。

I tried to update zoom level by sliding the slider input, which calls on handleZoomChange2 setting a new state to the zoom.我尝试通过滑动 slider 输入来更新缩放级别,这会调用 handleZoomChange2 将新的 state 设置为缩放。 However, the code throws an error Maximum call stack size exceeded.但是,代码会抛出错误 Maximum call stack size exceeded。 Please, help!请帮忙!

Error:错误:

TreeProfile.js:38 Uncaught RangeError: Maximum call stack size exceeded
at TreeProfile (TreeProfile.js:38:1)
at renderWithHooks (react-dom.development.js:16305:1)
at updateFunctionComponent (react-dom.development.js:19588:1)
at beginWork (react-dom.development.js:21601:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
at recoverFromConcurrentError (react-dom.development.js:25850:1)
at performSyncWorkOnRoot (react-dom.development.js:26096:1)

In case somebody stumbles upon this, here's the solution:万一有人偶然发现了这个,这里是解决方案:

Cause of the problem问题原因

Encoding of the image from array buffer tree.image.data.data to base64 was causing the error of Uncaught RangeError: Maximum call stack size exceeded .将图像从数组缓冲区tree.image.data.data编码为 base64 导致Uncaught RangeError: Maximum call stack size exceeded错误。 I'm not quite certain why exactly, somebody smarted than me may explain it.我不太确定为什么,比我聪明的人可能会解释。

<img style={{height: '200px', width: '300px'}} src={`data:image/${tree.image.contentType};base64,${btoa(String.fromCharCode(...new Uint8Array(tree.image.data.data)))}`} alt='' />

Solution解决方案

I found the solution to this problem from this Stackoverflow thread .我从这个 Stackoverflow 线程找到了解决这个问题的方法。 There they discuss the problem more in detail, however, here is the solution that worked for me.他们在那里更详细地讨论了这个问题,但是,这是对我有用的解决方案。

  const _arrayBufferToBase64 = ( buffer ) => {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
  }

here the buffer is tree.image.data.data (the array buffer of unit8array) and the function returns base64 encoded result.这里的缓冲区是tree.image.data.data (unit8array 的数组缓冲区),function 返回 base64 编码结果。 My code after these changes looks following这些更改后我的代码如下所示

import { Container } from "react-bootstrap"
import { useParams } from "react-router"
import apiService from "../services/apiService"
import { useEffect, useState } from "react"
import Spinner from 'react-bootstrap/Spinner';

const GOOGLE_API_KEY = process.env.REACT_APP_GOOGLE_API_KEY

export const TreeProfile = (props) => {
  const [tree, setTree] = useState(null)
  const [fetching, setFetching] = useState(true)
  const [zoom, setZoom] = useState("12")
  const [location, setLocation] = useState({latitude: "", longitude: ""})

  let { id } = useParams()

  console.log("Called TreeProfile")
  console.log("fetching", fetching)

  useEffect(() => {
    console.log("id", id)
    apiService.getOne(id).then(t => {
      console.log("data", t)
      setTree(t)
      setLocation({latitude: t.location.latitude, longitude: t.location.longitude})
      setFetching(false)
    })
  }, [])
  
  const handleZoomChange2 = (event) => {
    console.log(event.target.value)
    setZoom(event.target.value)
  }
  const test = (event) => {
    console.log(event.target.value)
    setFetching(!fetching)
  }

  const _arrayBufferToBase64 = ( buffer ) => {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
  }


  if (tree) {
    return (
      <Container className="treeprofile-page">
        <div>
          <img style={{height: '200px', width: '300px'}} src={`data:image/${tree.image.contentType};base64,${_arrayBufferToBase64(tree.image.data.data)}`} alt='' />
          <h1>{tree.name}</h1>
          <h3>Planted on {new Date(tree.createdAt).toDateString()}</h3>
          <h3>Planted by {tree.user}</h3>
          </div>
        <img src={`https://maps.googleapis.com/maps/api/staticmap?center=${location.latitude},${location.longitude}&format=gif&zoom=${zoom}&size=300x200&markers=color:red%7C${location.latitude},${location.longitude}&key=${GOOGLE_API_KEY}`} alt='' />
        <div>
          <input className="m-3" type="range" min="1" max="16" value={zoom} onChange={handleZoomChange2} />
        </div>
  
        <button type="button" className="btn btn-primary" onClick={test} >Add update</button>
        
      </Container>
    )
  } else {
    return (
      <Container>
        <Spinner animation="border" variant="primary" />
      </Container>
    )
  }
  
}

Hope this helps anybody facing the same problems!希望这可以帮助任何面临同样问题的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM