react-异常状态记录

遇到什么写什么。
由于最近在使用ant-design,所以这里还会涉及与它相关的问题。

1.

日志信息:React does not recognize the `fieldType` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `fieldtype` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
问题来源:react
原因:DOM节点中被传入了组件属性

const resPorps={
  fieldType:'.txt',
  marginLeft:10,
};
return(
  <div {...resProps}>
    test
  </div>
)

如上,fieldType不属于DOM的默认属性,对于React来说,这是一种冗余的写法。
解决办法:将不属于DOM的属性提取出来

const resPorps={
  marginLeft:10,
};
return(
  <div {...resProps} fieldType='.txt'>
    test
  </div>
)

2.

日志信息:Each child in an array or iterator should have a unique "key" prop.Encountered two children with the same key
问题来源:react,ant-design
原因:第一个警告是由于数组循环时缺少unique "key" prop,即一个不会重复的关键参数key。如果出现了重复,则会引起第二个警告,并且在对数据进行操作时,如增删查改,会出现错误(特别是在使用Ant-design的table组件时)。
解决办法:为数组添加唯一的key值。
拓展:react为什么要设置唯一的key值?(React中key的必要性与使用)
在了解这个问题前,我们需要知道react的工作机制。
React框架的核心思想是,将页面分割成一个个组件,一个组件还可能嵌套更小的组件,每个组件都有自己的数据(属性/状态),并且只关心自己部分的逻辑,彼此独立;当某个组件的数据发生变化时,新的数据自该组件顶层向下流向子组件,每个组件调用自己的render方法得到新的视图,并与之前的视图作diff-比较差异,完成视图更新(reconciliation-调和)。
基于Reac开发的所有DOM都是通过virtual dom来实现的。当数据更新时,react利用纯js根据组件们的render方法计算出新的虚拟dom树,并与此前的虚拟dom树作diff,得到一个patch(差异补丁),最后将patch映射到真实dom树上完成视图更新。
由于React采用的diff算法是对新旧虚拟dom树同层级的元素挨个比较,就会发现当react遇到循环输出元素时,就会出现一些问题,比如表格、列表等。
以列表为例:

//旧   
<ul>  
  <li>first</li> 
  <li>second</li>
</ul> 
//新
<ul>
  <li>zero</li>
  <li>first</li>
  <li>second</li>
</ul> 

可以看出,上面的操作是在first前插入一条新的数据zero,原有的数据向后移一位。但是对于react来说,新的DOM树与旧的DOM树是完全不同的,原来的两个li元素都与新v-dom中对应位置上的两个li元素不同,它会对整个ul列表进行更新,即将旧的<li>first</li>变为<li>zero</li>,旧的<li>second</li>变为<li>first</li>, 最后新增一个<li>second</li>节点,这增加了额外的修改操作。
解决这个问题的方法是使用一个唯一的key值,用来唯一标识同父同层级的兄弟元素。当React作diff时,只要子元素有key属性,便会去原v-dom树中相应位置(当前横向比较的层级)寻找是否有同key元素,比较它们是否完全相同,若是则复用该元素,免去不必要的操作。

3.

日志信息:You cannot set a form field before rendering a field associated with the value.
问题来源:ant-design
原因:在给form表单赋值时,form表单还未注册。
解决方法:还未解决。

4.

日志信息: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.
问题来源:react
原因:跳转路由时,当前组件被销毁,但是组件内部还存在异步操作对state的状态信息 比如http请求,定时器setTimeOut更新state等。
解决方法:(React 警告和异常整理)
解决方案一:组件被销毁之前重写setState方法 不对状态做任何改变

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

解决方案二:组件被销毁之前 可以setState 销毁之后就不能setState

 componentWillMount() {
        this._isMounted = true
        fetch('网络请求').then (status, response)=>{
          if (this._isMounted) {
            this.setState({
                activityTipsImg: response.data.tips_url,
                activityTipsContent: response.data.tips_content
            })
          }
        });
}
componentWillUnmount() {
        this._isMounted = false
}

5.

日志信息:Style prop value must be an object react/style-prop-object
问题来源:react
原因:在React框架的JSX编码格式要求,style必须是一个对象。
解决方法:除了外部那个表示Javascript语句的花括号外,里面必须再写一个花括号{}包含的对象,例如<div style={ { color:“blue” } }></div>,外部的{ }表示这是Javascript句法,里面的{ }表示这是一个对象。

6.

日志信息:validateDOMNesting(...): <tr> cannot appear as a child of <table>
问题来源:react
原因:在React中<tr>元素不可以作为<table>元素的直接子元素。
解决方法:在<tr>元素tbody和<table>元素中间插入<tbody>元素,如:

<table>
  <tbody>
    <tr>
        <td></td>
    </tr>
  <tbody>
</table>

7.

日志信息:Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
问题来源:react
原因:<input />设置了value的话,输入框的值将一直展示为value的值,是不可改变的,要想改变的话,需要通过onChange
解决方法:要是该输入框的值不需要修改,这可以将input的属性设置为readOnly,否则的话应该使用defaultValue来设置输入框的初始值。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容