Error in render rangeerror maximum call stack size exceeded

I cannot pass data from parent to child. I am using props, have tried returning data as well - no luck. I have a panel component (which is parent) with data and panelBody component (child) Panel i...

The reason you have the error

Maximum call stack size exceeded

is because of this

import PanelBody from '../components/PanelBody'
export default {
  name: 'panel-body',
  components: {
    'panel-body': PanelBody
  },

You defined your Panel component with name: 'panel-body'. Change that to name: 'panel', and you will remove your circular reference.

The other issues mentioned in comments and the other answer generally apply as well. Here are working versions of your components.

Panel.vue

<template>
  <div id="panel">
    <div class="panel">
      <ul>
        <li v-for="shelf in shelfs">
          <panel-body :shelf="shelf" :key="shelf.name" :selected.sync="selected"></panel-body>
        </li>
      </ul>
    </div>
    {{selected}}
  </div>
</template>

<script>
import PanelBody from './PanelBody.vue'
export default {
  name: 'panel',
  components: {
    'panel-body': PanelBody
  },
  data(){
    return {
    shelfs: [{
      name: 'shelf 1',
      books: [{
        title: 'Lorem ipum'
      }, {
        title: 'Dolor sit amet'
      }]
    }, {
      name: 'shelf 2',
      books: [{
        title: 'Ipsum lorem'
      }, {
        title: 'Amet sit dolor'
      }]
    }],
    selected: {}

    }
  }
}
</script>

<style scoped>
a {
  color: #42b983;
}
</style>

PanelBody.vue

<template>
  <div id="panel-body">
    <a href="#" v-on:click.prevent.stop="select">{{ shelf.name }}</a>
    <ul v-show="isSelected">
      <li v-for="book in shelf.books">{{ book.title }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'panel-body',
  props: ['shelf', 'selected'],
  data(){
    return {
      internalSelected: null
    }
  },
  computed: {
    isSelected: function () {
      return this.internalSelected === this.shelf
    }
  },
  methods: {
    select: function () {
      this.internalSelected = this.shelf
      this.$emit("update:selected", this.internalSelected)
    }
  }
}
</script>

<style scoped>
a {
  color: #42b983;
}
</style>

I wanted to note one more thing. Because of this line in PanelBody, this.selected = this.shelf Vue will throw a warning that you are mutating a prop directly. Generally you should store a local copy of a property that you are going to mutate. I’ve updated the code above to do that.

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Comments

@konstantinrachev

Version

2.5.14

Reproduction link

https://jsfiddle.net/50wL7mdz/175425/

Steps to reproduce

  1. Including vue(v.2.5.14) and element.io styles and library.
  2. Opening new form.
  3. Opening new form element.
  4. Using custom date picker element.

What is expected?

It is expected to render a custom UI component for date picking.

What is actually happening?

The element is not being render as the console is filled with errors.

[Vue warn]: Error in render: «RangeError: Maximum call stack size exceeded», vue.js:597
RangeError: Maximum call stack size exceeded, vue.js:1745


The issue is related to the latest vue.js version as it is working as expected with all up to 2.5.13.

@posva

@dorianWB

I still get this error, but I haven’t got the time to put together a reproduction case right now. I know that it exists in 2.5.16 still and going back to 2.5.13 resolves the issue and the error looks like RangeError: Maximum call stack size exceeded at Function.[Symbol.hasInstance] (<anonymous>) at t (app.c84200b64a284b43c3fe.js:1) which t is the _traverse function and the error is in

function _traverse (val: any, seen: SimpleSet) {
let i, keys
const isA = Array.isArray(val)
if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
return
}

@rowild

I also get this error, when document.querySelector() tries to bind DOM to a configuration element, that is set to store.config via a mutation. (The function is called from root element’s mounted() ) …

EDIT: happens only, when store is in strict mode.

@Darkside73

Confirming this issue when store in a strict mode (using nuxt)

@sarkiroka

Confirming too with v2.5.15 and v2.5.17

@kvnify

I’m possibly seeing this as well. Can confirm that disabling strict mode in the vuex store seemed to fix the issue.

@konstantinrachev

Yeah, strict mode does seem to fix the issue.

@Gyanxie

var selfObj= {};
selfObj.self = selfObj;
new Vue({
computed: { selftWatch: function get() { return selfObj; } } ,
watch: {
selftWatch: {
deep: true,
handler: function () { console.error(‘seccess run ‘)}
}
}
});
看了下 _traverse 方法,没有对 对象去重,应该记录所有对象的引用。

@sellingsolutions

I was brought to this issue by searching for:
Error in render: «RangeError: Maximum call stack size exceeded

However, it didn’t have anything to do with the naming of components. It’s probably related to what @Gyanxie posted above.

My offender was the code snippet below:

watch: {
    '$vuetify.breakpoint': {
      handler: function(newBreakpoint) {},
      deep: true,
      immediate: true
    }
}

This might prove useful to the next person that runs into this cryptic error message

Ситуация: заказчик попросил разместить на странице кликабельную картинку, а чтобы на неё обратило внимание больше посетителей, попросил сделать вокруг неё моргающую рамку. Логика моргания в скрипте очень простая:

  1. В первой функции находим на странице нужный элемент.
  2. Добавляем рамку с какой-то задержкой (чтобы она какое-то время была на экране).
  3. Вызываем функцию убирания рамки.
  4. Внутри второй функции находим тот же элемент на странице.
  5. Убираем рамку с задержкой.
  6. Вызываем первую функцию добавления рамки.

Код простой, поэтому делаем всё в одном файле:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Pulse</title>
	<style type="text/css">
	/*	рамка, которая будет моргать	*/
		.pulse { box-shadow: 0px 0px 4px 4px #AEA79F; }
	</style>
</head>
<body>
	<div id="pulseDiv"> 
    	<a href="#">
      		<div id="advisersDiv">
        		<img src="https://thecode.media/wp-content/uploads/2020/08/photo_2020-08-05-12.04.57.jpeg">
        	</div>
      	</a>
</div>
<!-- подключаем jQuery -->
<script src="https://yastatic.net/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<!-- наш скрипт -->
<script type="text/javascript">
	// добавляем рамку
	function fadeIn() {
		// находим нужный элемент и добавляем рамку с задержкой
  	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
  	// затем убираем рамку
  	fadeOut();
	};
	// убираем рамку
	function fadeOut() {
		// находим нужный элемент и убираем рамку с задержкой
   	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
   	// затем добавляем 
   	fadeIn();
	};
	// запускаем моргание рамки
	fadeIn();
</script>

</body>
</html>

Но при открытии страницы в браузере мы видим, что ничего не моргает, а в консоли появилась ошибка:

❌ Uncaught RangeError: Maximum call stack size exceeded

Что это значит: в браузере произошло переполнение стека вызовов и из-за этого он не может больше выполнять этот скрипт.

Переполнения стека простыми словами означает вот что:

  1. Когда компьютер что-то делает, он это делает последовательно — 1, 2, 3, 4.
  2. Иногда ему нужно отвлечься от одного и сходить сделать что-то другое — а, б, в, г, д. Получается что-то вроде 1, 2, 3 → а, б, в, г, д → 4.
  3. Вот эти переходы 3 → а и д → 4 — это компьютеру нужно запомнить, что он выполнял пункт 3, и потом к нему вернуться.
  4. Каждое запоминание, что компьютер бросил и куда ему нужно вернуться, — это называется «вызов».
  5. Вызовы хранятся в стеке вызовов. Это стопка таких ссылок типа «когда закончишь вот это, вернись туда».
  6. Стек не резиновый и может переполняться.

Что делать с ошибкой Uncaught RangeError: Maximum call stack size exceeded

Эта ошибка — классическая ошибка переполнения стека во время выполнения рекурсивных функций.

Рекурсия — это когда мы вызываем функцию внутри самой себя, но чуть с другими параметрами. Когда параметр дойдёт до конечного значения, цепочка разматывается обратно и функция собирает вместе все значения. Это удобно, когда у нас есть чёткий алгоритм подсчёта с понятными правилами вычислений.

В нашем случае рекурсия возникает, когда в конце обеих функций мы вызываем другую: 

  1. Функции начинают бесконтрольно вызывать себя бесконечное число раз.
  2. Стек вызовов начинает запоминать вызов каждой функции, чтобы, когда она закончится, вернуться к тому, что было раньше.
  3. Стек — это определённая область памяти, у которой есть свой объём.
  4. Вызовы не заканчиваются, и стек переполняется — в него больше нельзя записать вызов новой функции, чтобы потом вернуться обратно.
  5. Браузер видит всё это безобразие и останавливает скрипт.

То же самое будет, если мы попробуем запустить простую рекурсию слишком много раз:

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Как исправить ошибку Uncaught RangeError: Maximum call stack size exceeded

Самый простой способ исправить эту ошибку — контролировать количество рекурсивных вызовов, например проверять это значение на входе. Если это невозможно, то стоит подумать, как можно переделать алгоритм, чтобы обойтись без рекурсии.

В нашем случае проблема возникает из-за того, что мы вызывали вторые функции бесконтрольно, поэтому они множились без ограничений. Решение — ограничить вызов функции одной секундой — так они будут убираться из стека и переполнения не произойдёт:

<script type="text/javascript">
// добавляем рамку
function fadeIn() {
	// находим нужный элемент и добавляем рамку с задержкой
	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
	// через секунду убираем рамку
	setTimeout(fadeOut,1000)
};
// убираем рамку
function fadeOut() {
	// находим нужный элемент и убираем рамку с задержкой
 	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
 	// через секунду добавляем рамку
	setTimeout(fadeIn,1000)
};
// запускаем моргание рамки
fadeIn();
</script>

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Вёрстка:

Кирилл Климентьев

The error “Uncaught RangeError: Maximum call stack size exceeded” is common among programmers who work with JavaScript. It happens when the function call exceeds the call stack limit.

Let us look at the error in detail and the solution too.  

What do you Mean by Maximum Call Stack Error?

This error is caused mainly due to the following reasons –

Non-Terminating Recursive Functions

Your browser will allocate a certain amount of memory to all data types of the code you are running. But this memory allocation has a limit. When you call a recursive function, again and again, this limit is exceeded and the error is displayed.

So, call recursive functions carefully so that they terminate after a certain condition is met. This will prevent the maximum call stack to overflow and the error will not pop up.

Problematic Ranges

Some JS programs have ranges of inputs that the user can give. Other programs have functions that may go out of range. When this happens, browsers like Google Chrome will give you the Uncaught RangeError message. But Internet Explorer will crash.

To prevent this, always check the validity of input ranges and how the functions are working with the ranges.

Let us look at an example.

Example

<script>
fun_first();
function fun_first(){
console.log('Hi');
               fun_first();
}
</script>

Uncaught RangeError: Maximum call stack size exceeded

Explanation

In the above example, we are recursively calling fun_first() due to which the error is Uncaught RangeError encountered. The recursive function is called, which then calls another function, and goes on until it exceeds the call stack limit.   

Solution

We should call a recursive function with an If condition. When the code satisfies the condition, the function execution is stopped.

Code Example

<script>
var i=1;
fun_first(i);
function fun_first(i){
               if (i <= 10){
                              console.log('Hi');
                              i=i+1;
                              fun_first(i);
               }
}
</script>

In the above example, we have created an if condition to check the value of i. If the value of i reaches 10, the same function will not be called again.

Conclusion

The Uncaught RangeError is caused when the browser’s hardcoded stack size is exceeded and the memory is exhausted. So, always ensure that the recursive function has a base condition that can stop its execution.   

Понравилась статья? Поделить с друзьями:
  • Error in registration please correct the errors below and resubmit
  • Error in redirect data domain missing or malformed in
  • Error in receiving certificate authority certificate status fail cert length 0
  • Error in query 1064 syntax error near pk at line 1
  • Error in processheader 1 неверная функция