遇到什么写什么。
由于最近在使用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
来设置输入框的初始值。