簡體   English   中英

獲取未捕獲的 RangeError:React 中超出了最大調用堆棧大小

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

我是 React 的初學者,我一直在為 uni 中的一門課程編寫一個項目。 但是,我現在已經為以下錯誤苦苦掙扎了一段時間:Uncaught RangeError: Maximum call stack size exceeded。 我試圖找到一個沒有運氣的解決方案。

這是導致錯誤的 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>
  )
}

`

每次我嘗試通過滑動 slider 來更新縮放級別時都會發生錯誤,它調用設置 state 的 handleZoomChange2 function。我在不同的路徑中有其他組件具有相同的功能並且它工作正常。 但是,由於某種原因,這個錯誤不斷地導致錯誤。

apiService 從后端獲取 axios 的數據,后端又從 MongoDB 獲取數據。

我嘗試通過滑動 slider 輸入來更新縮放級別,這會調用 handleZoomChange2 將新的 state 設置為縮放。 但是,代碼會拋出錯誤 Maximum call stack size exceeded。 請幫忙!

錯誤:

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)

萬一有人偶然發現了這個,這里是解決方案:

問題原因

將圖像從數組緩沖區tree.image.data.data編碼為 base64 導致Uncaught RangeError: Maximum call stack size exceeded錯誤。 我不太確定為什么,比我聰明的人可能會解釋。

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

解決方案

我從這個 Stackoverflow 線程找到了解決這個問題的方法。 他們在那里更詳細地討論了這個問題,但是,這是對我有用的解決方案。

  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 );
  }

這里的緩沖區是tree.image.data.data (unit8array 的數組緩沖區),function 返回 base64 編碼結果。 這些更改后我的代碼如下所示

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>
    )
  }
  
}

希望這可以幫助任何面臨同樣問題的人!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM