一、死循环

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. scala简单的功能实现~weekone

    以下是scala简单的入门题~ 1.⼀个数字如果为正数,则它的signum为1:如果是负数,怎么signum为-1:如果是0,则signum 为0.编写⼀个函数来计算这个值. object Test ...

  2. hive中的日期转换函数

    1.unix时间戳转时间函数   语法: from_unixtime(bigintunixtime[, string format]) 返回值: string   说明: 转化UNIX时间戳(从197 ...

  3. 使用async/await消除callback hell

    使用async/await消除callback hell 通过Future回调中再返回Future的方式虽然能避免层层嵌套,但是还是有一层回调,有没有一种方式能够让我们可以像写同步代码那样来执行异步任 ...

  4. redux学你参考网站

    redux官方网站 http://cn.redux.js.org/docs/api/combineReducers.html https://www.redux.org.cn 从设计的角度看Redux ...

  5. (4)给树莓派安装中文输入法Fcitx及Google拼音输入法

    sudo apt-get install fcitx fcitx-googlepinyin fcitx-module-cloudpinyin fcitx-sunpinyin 安装完毕,重启即可.

  6. centos7.2(一)vultr服务器购买和开通端口

    https://vultr.me/52.html 之前我们已经介绍了如何购买 Vultr 以及如何使用支付宝对 Vultr 进行充值,相关教程: VULTR 购买教程 2018 年最新图文版 VULT ...

  7. linux学习13 Linux运维常用文件管理命令及系统变量基础

    一.文件管理命令 1.cp命令,copy a.单源复制,cp [OPTION]... [-T] SOURCE DEST 如果DEST不存在:则事先创建此文件,并复制源文件的数据流至DEST中. 如果D ...

  8. blessed-contrib 开发终端dashboard 的几点说明

    以前有说过blessed-contrib 这个很不错的终端dashboard 开发框架,以下是使用中的一些问题 中文编码 模式是不支持中文编码的,但是 我们可以在初始化的时候指定unicode编码 s ...

  9. cronicle docker 运行试用

    Cronicle 是一款基于nodejs 开发的分布式任务调度工具,包含了比较全的UI,使用也比较简单,为了 方便学习,简单制作了一个docker 镜像,方便使用 Dockerfile   FROM ...

  10. Filters in ASP.NET Core

    Filters in ASP.NET Core allow code to be run before or after specific stages in the request processi ...