添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

今天在使用React的时候发生了死循环情况,现在拿出来跟大家讨论讨论,其中大致代码如下:

import React from 'react';
import ReactDOM from 'react-dom';
const Button = ({ onClick, children }) => {
    return (
        <button type="button"
            onClick={event => {
                if (!!onClick) {
                    onClick(event);
            }}>{children}</button>
function handleClick() {
    this.setState({count:++this.state.count});
    console.log("click done!");
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state={count :0,color:"red"}
    componentDidMount() {
    render() {
        return (
                <Button onClick={handleClick.call(this)}>点我</Button>
                {this.state.count}
            </div>
export default App;
ReactDOM.render(<App />, document.querySelector("#app"));

运行后浏览器会报这样的错误:

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

在低版本的React可能不会出现上面这样的错误,而直接进入死循环中,直到内存消耗殆尽。

问题分析:

代码的效果很简单就是点击一下按钮,数字加一下。这里把按钮封装了一下。请看render方法里面的onClick方法,这里调用handleClick.call(this)而这个并不是一个函数,而是函数的执行,所以到这一行React会执行这个函数,但是函数里面又调用了setState方法,这个方法改变状态后又会重新渲染DOM,也就会再次调用render方法。同样的,该方法执行的时候又会调用handleClick.call(this),再次循环上面的逻辑,因此陷入了死循环之中。

解决问题:

这里handleClick.call(this)有问题,我们调用这的目的是为了绑定this,而不需要执行,所以这行代码改成handleClick.bind(this)即可。当然还有另外一种解决办法,就是在方法中调用函数,代码如下:

<Button onClick={()=>{
    handleClick.call(this)
    }}>点我</Button>
扩展延伸:

这里出现错误的原因是有call方法调用所导致的,那么我们很有必要了解一下callapplybind三个方法的区别,这三者都是用来改变this的指向的,但是也有不一样的地方,具体区别如下:

1.callapply的效果是一样的都是绑定this,并且调用。只是语法有所区别。call绑定this的语法是这样的func.call(this, arg1, arg2),apply绑定this的语法是这样的func.apply(this, [arg1, arg2])。也就是说除了第一个参数是绑定对象外,call的参数和原本的函数调用顺序是一致的,但是apply的第二个参数是原先参数的一个数组形式。
2.bind是ES5(几乎现在所有的主流浏览器都支持)增加语法,它只是绑定this,但不会立即调用。

今天学习React的时候,一不小心踩到了坑,进入了无限死循环,导致直接溢出内存,报错 Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite lo. 很多人认为 React 是 MVC 中的 V(视图)。 我们创造 React 是为了解决一个问题:构建随着时间数据不断变化的大规模应用程序。为了达到这个目标,React 采用下面两个主要的思想。 仅仅只要表达出你的应用程序在任一个时间点应该长的样子,然后当底层的数据变了,React 会自动处理所有用户界面的更新。 声明式 (Declarative) 数据变化后,React 概念上与点击“刷新”按钮类似,但仅会更新变化的部分。 qnn-react-cron 可以看做 react-cron-antd 的升级版(具体“渊源”可见文档),现有功能如下: - 🎉 全面支持 cron:秒、分、时、日、月、周、年 - 🎉 日及周条件互斥,自动改变响应值 - 🎉 支持反解析 cron 表达式到 UI - 🎉 可结合此组件与 Antd 的下拉及输入组件封装成下拉输入框 - 🎉 国际化支持 - 🎉 TypeScript 支持 Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState.... 问题分析 Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops. Warning: Cannot update during an Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinit... 最近进入了项目组,把之前的代码拉了下来,前段时间大致看了看。 上周学长让我把项目里面的一些老东西给改一改,比如一些string的ref,以及一些即将废弃的生命周期函数,例如:componentWillReceiveProps,componentWillMount等等 ref修改的很顺利,但是生命周期函数修改的很麻烦,因为一些函数componentWillReceiveProps,componentWillMount等等,是无法找到完美替代的新的生命周期函数的,新推出的getDerivedStateFro React项目报错 Unhandled Rejection (Error): Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops. Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.