一、死循环

1、问题描述

function handleClick() {
    this.setState({count: ++this.state.count});
    console.log("click done!");
}

render() {
    return <Button onClick={this.handleClick()}>提交</Button>;
}
// 页面运行后,浏览器报错。在低版本的React可能不会出现上面这样的错误,而直接进入死循环中,直到内存消耗殆尽。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.

2、问题分析

render里面是函数执行,而函数调用了setState,改变状态后又会重新渲染DOM,也就会再次调用render方法。归结到js基础call,bind的区别。

3、解决方案

// 方案A
<Button onClick={this.handleClick.bind(this)}>提交</Button>;

// 方案B
<Button onClick={() => { this.handleClick();}}>提交</Button>;

二、数据更新,视图未更新

1、问题描述

数据变了,父组件和子组件都能拿到最新数据,但是子组件一直在死循环,页面没有重新渲染。
// 父组件graph.queryObjList = _.cloneDeep(objArr);

2、问题分析

父组件传值有问题,父组件改变了子属性,子组件取不到最新的queryObjList,React Diff算法认为graph没有变,就不会去更新。归结为js基础,赋值,拷贝,数据类型存储问题。
3、解决方案
let graphClone = _.cloneDeep(graph);
graphClone.queryObjList = _.cloneDeep(objArr);

三、列表key唯一性

1、参考文档

https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

https://reactjs.org/docs/reconciliation.html#recursing-on-children

2、期望结果

3、实际结果

4、问题描述

想删除中间的某一个,但结果却删除的最后一个。如果只是新增但是不填写内容,那么删除了也无所谓,但如果新增后填写再删除就出问题了。

5、问题分析

React元素可以具有一个特殊的属性key,这个属性不是给用户用的,而是给React用的。如果我们动态地创建React元素,而且React元素内包含数量或顺序不确定的子元素时,我们就需要提供key这个特殊的属性。react利用key来区分组件的,相同的key表示同一个组件,react不会重新销毁创建组件实例,只可能更新;key不同,react会销毁已有的组件实例,重新创建组件新的实例。如果纯渲染,key用索引赋值,没问题;但是,如果是动态增删元素,对元素进行排序,就有问题。key需要唯一的id,不要用0,1,2这种。

6、解决方案

//方案A,推荐
import shortid from 'shortid';
shortid.generate();

//方案B,推荐
时间戳
const date = +new Date();

//方案C
import uuidv4 from  'uuidv4';
uuidv4(); 

// 使用,添加的时候,用shortid或者时间戳作为添加数据的id。 key不要写Index
<form className="form-horizontal">
    {
        this.state.list.map((value, index) =>
            <Item {...value} key={value.id} />
        )
    }
</form>

四、诡异跳转

1、问题描述

给按钮绑定事件,事件什么都不写,调试程序时,发现点击按钮后,页面从http://127.0.0.1:8080跳转刷新到http://127.0.0.1:8080/?为什么会多一个问号。

<form>
  <button onclick={this.handleDelete.bind(this)}>dddddd</button>
</form>

2、问题分析

3、问题解决

<div>
  <button onclick={this.handleDelete.bind(this)}>dddddd</button>
</div>

五、性能问题

1、问题描述

Warning: Can’t call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

2、问题分析

  • 使用了React Router,从一个页面跳转到了另一个页面。当组件被unmount之后,你仍然可能会调用该组件的this.setState()方法,比如你在该组件内部有异步操作(通常是网络请求)发生,在异步操作结束之后,你可能需要更新该组件的state。
  • 你在组件内,向某个API接口发起了异步请求,在请求结束之前,你的组件被unmount了。在这之后,请求响应,你需要根据响应的内容,调用组件的this.setState()来更新状态,然而,这时该组件已经被unmount了;
  • 你在组件内,绑定了一个事件回调函数,但是没有在组件的componentWillUnmount里取消事件绑定。在组件被unmount之后,该事件回调函数可能会被调用;
  • 你在组件内,有一个定时器(interval),你在计时器的回调函数里,调用了this.setState()来更新组件状态。如果你忘记了在componentWillUnmount里清除掉定时器,那么就会像上面那样,在unmount的组件上更新state;

3、问题解决

  • 怎样避免在定时器/事件回调里调用unmounted组件的setState?

在componentWillUnmount里,清除定时器,取消事件绑定。

  • 怎样避免在异步请求里调用unmounted组件的setState?

你可以在组件unmount的时候,中断网络请求,或者在网络结束时,避免调用this.setState() 。然而,大多数基于Promise的网络请求库,都没有提供中断网络请求的功能,因此我们需要自己在组件类上,增加一个类的实例属性来标记当前组件是否已经mount了。这个标记默认是false的,之后在组件的componentDidMount里,标记设置为true;在组件的componentWillUnmount里,设置为false。通过这个属性,我们能够知道当前组件是否处于mount之后。这个属性不会受this.setState()的影响,因为它是实例属性,我们能够直接在组件实例上访问它,不需要经过react组件的this.state。因为它不在组件的state上,我们修改这个属性,也就不会触发组件重新render了。

class News extends Component {
  _isMounted = false;

  constructor(props) {
    super(props);

    this.state = {
      news: []
    };
  }

  componentDidMount() {
    this._isMounted = true;

    axios
      .get('https://www.baidu.com/api/search?query=react')
      .then(result => {
        if (this.isMounted) {
          this.setState({
            news: result.data.hits,
          });
        }
      });
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  render() {

  }
}

六、警告报错

1、问题描述

Warning: React does not recognize the computedMatch prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase computedmatch instead. If you accidentally passed it from a parent component, remove it from the DOM element.

2、问题分析

因为在react-router-dom的switch中使用了div。

<Router>
  <Switch>
     <div>
         <Route path="/" exact component={Home}>
     </div>
  </Switch>
</Router>

3、解决方案

把div改成Fragment。

<Router>
  <Switch>
     <React.Fragment>
         <Route path="/" exact component={Home}>
     </React.Fragment>
  </Switch>
</Router>

七、位置残留

1、问题描述

在A页面滚动到底部,跳转到B页面,发现也是滚动到底部,如何能新加载B页面?

2、问题分析

这是react-router的问题,不维护scroll position,需要自己解决。

3、解决方案

自己写回调,滚动到顶部。

import { withRouter } from "react-router-dom";
class ScrollToTop extends Component {
    componentDidUpdate(prevProps) {
        if (this.props.location.pathname !== prevProps.location.pathname) {
            document.getElementById("page").scrollTo(0, 0);
        }
    }
    render() {
        return this.props.children;
    }
}
const PageContainer = withRouter(ScrollToTop);
<Router>
  <PageContainer>
    {/* 你的正常的渲染内容 */}
  </PageContainer>
</Router>

八、组件切换,出现报错

1、问题描述

Warning: Can't perform a React state update on an unmounted component. 

2、问题分析

3、解决方案

componentWillUnmount() {
        this.setState = () => {
            return;
        }
}

九、图片加载报错无限循环

1、问题描述

一直循环报错找不到图片,直到浏览器崩溃。

2、问题分析

因为react在前端对应的url下面找不到图片资源,因为那个图片资源不存在,你没有放进去,或者资源放得位置和引用地址不一致。

3、解决方案

把图片放在正确的位置,并引用正确的相当路径。

react一些问题的更多相关文章

  1. react组件的生命周期

    写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...

  2. 十分钟介绍mobx与react

    原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...

  3. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  4. React 入门教程

    React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...

  5. 通往全栈工程师的捷径 —— react

    腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...

  6. 2017-1-5 天气雨 React 学习笔记

    官方example 中basic-click-counter <script type="text/babel"> var Counter = React.create ...

  7. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

  8. React在开发中的常用结构以及功能详解

    一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...

  9. React的使用与JSX的转换

    前置技能:Chrome浏览器   一.拿糖:React的使用 React v0.14 RC 发布,主要更新项目: 两个包: React 和 React DOM DOM node refs 无状态的功能 ...

  10. Vue.js 2.0 和 React、Augular等其他框架的全方位对比

    引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...

随机推荐

  1. 利用 subst.exe 可以将任意文件夹映射成盘符:

    subst命令:将路径与驱动器号关联,即将一个目录当做一个磁盘驱动器来看: 假设:将E:\下的baidu文件夹设置成虚拟盘,虚拟盘的盘符为M. 1.点开始按钮,在运行框里输入 subst m: E:\ ...

  2. Find the Weak Connected Component in the Directed Graph

    Description Find the number Weak Connected Component in the directed graph. Each node in the graph c ...

  3. ansible部署EFK

    修改自己不确定的配置文件前,先准备备份,防患于未然!!! Environment:{ 目前测试准备三台2m2g虚拟机  详情概略图见EFK的架构图 https://www.cnblogs.com/se ...

  4. 02_搭建HTTP客户端与服务器(数通华为)

    1.选择客户端和服务端: 2.服务端创建HTTP目录: 3.客户端访问下载:

  5. Numpy | 08 切片和索引

    ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样. (1)ndarray 数组索引可以基于 0 - n 的下标进行: (2)切片对象可以通过内置的 ...

  6. Shell 变量自增实现方法

    i=`expr $i + `; let i+=; ((i++)); i=$[$i+]; i=$(( $i + )) 参考: https://www.cnblogs.com/faithfu/p/9472 ...

  7. HashMap多线程并发问题分析-正常和异常的rehash1(阿里)

    多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变 ...

  8. 【Beta】Scrum meeting 10

    目录 写在前面 进度情况 任务进度表 Beta-1阶段燃尽图 遇到的困难 照片 commit记录截图 后端代码 前端代码 技术博客 写在前面 例会时间:5.14 22:30-22:45 例会地点:微信 ...

  9. Gaze Estimation学习笔记(2)-It's Written All Over Your Face Full-Face Appearance-Based Gaze Estimation

    目录 前言 将完整脸部图像作为输入的空间权重CNN方法 将full-face image作为输入的原因 加入空间权重的CNN方法 基础CNN结构 空间权重机制 实验及分析 头部姿态.面部表现视线方向的 ...

  10. Spring Cloud 学习--Hystrix应用

    上一篇介绍了Hystrix基本功能和单独使用的方式,今天继续学习如何将Hystrix融入SpringCloud组件中去. 在Ribbon上使用熔断器 在 pom.xml 文件中引入 hystrix 的 ...