原因:页面刷新进入了死循环,导致页面崩溃! 然后白屏了,,,
场景描述:
页面是一个 ip 区间,在区间后面显示 一组数据是否都存在区间内的,都存在显示 √,部分存在显示 ×,并显示不存在区间内的 ip
Console报错信息:Too many re-renders. React limits the number of renderers to prevent an infinite loop...
页面崩溃的代码:
const [ errorIps, setErrorIps]= useState<string[]>([]);
//页面
<Row>
<ipInput> </Input> //IP区间的控件
{ //状态显示
seeError(items[index].value)?
<span> √ </span>
: <span> ×
<Popover
title="错误 IP "
content={
<div>{ errorIps }</div>
}
>
<a>查看</a>
</Popover>
</span>
}
</Row>
//判断方法
const seeError=(value:string[]):string[]=>{
let errors:string[]=[];
props.List.map((item)=>{
value.map((ele)=>{
if(ele===item){
errors.push();
}
setErrorIps(errors);
});
});
}
崩溃原因:每当页面渲染时,会触发seeError方法,方法中每次都会重置errors数组,errors数组状态每次更新会引起页面重新渲染,页面渲染又会触发seeError方法,,,,因此进入了无穷无尽的页面渲染,导致页面崩溃。。。
正确的代码:(不让页面渲染时更新状态)
const [errors, setErrors]= useState<string[]>([]);
//页面
<Row>
<ipInput> </Input> //IP区间的控件
{ //状态显示
seeError(items[index].value).length===0?
<span> √ </span>
: <span> ×
<Popover
title="错误 IP "
content={
<div>{ seeError(items[index].value).join(',')}</div>
}
>
<a>查看</a>
</Popover>
</span>
}
</Row>
//判断方法
const seeError=(value:string[]):string[]=>{
let errors:string[]=[];
props.List.map((item)=>{
value.map((ele)=>{
if(ele===item){
errors.push();
}
//setErrors(errors); //这个就不要了
});
});
//取而代之,return这才是最重要的
if( props.List.length === errors.length && errors=== 0){ //条件是业务的需要
return [];
}else{
return errors;
}
}
注:也不是说所有的页面渲染不能 setState(),这个页面是触发了函数,函数里触发了setState,而这个state是个数组,只要触发一定会使页面重新渲染。
有些布尔型或者number、string,基本类型是可以在页面更改的,react本身会判断一下是否相等,不等才更新,才会渲染。
另外,白屏由各种各样的原因导致,比如,内存泄漏、代码死循环,页面崩溃等,那么遇到了白屏我们不要怕,我们一步步来解决,首先先排查哪一块导致了白屏,白屏时Console里有没有报错信息,Network里的接口调用的情况,Performance里的内存变化等,定位到了原因就好解决了。