开门见山,先看一张bug图(status下有个00)。期望是:当状态为0时,这2个组件不渲染。Status:当status为0时,两个组件都没有渲染,但是00渲染了。零渲染bug代码如何修复零渲染问题先看源码源码疑惑及原因源码总结实锤零渲染bug代码什么是React的零渲染问题?看下面一段代码,我们经常这样写://错误代码0{obj?.count&&{obj?.count}}如果obj?.count为0,渲染结果是0。这里不是只有一个0吗,为什么上面是00。//错误代码00{obj?.countFoo&&{obj?.countFoo}}{obj?.countBar&&{obj?.countBar}}当obj?.countFoo和obj?.countBar都为0,渲染结果为00如何解决渲染为零的问题{!!obj?.count&&{obj?.count}}or{obj?.count?{obj?.count}:null}或者{Boolean(obj?.count)&&{obj?.count}}首先看源码原因(点击输入查看源代码):React组件将渲染字符串、数字。不会呈现null、undefined、boolean。源码混乱既然boolean会被处理成null,为什么true&&可以正常渲染?先说结论吧,因为有了&&操作,React最终渲染出来的是jsx和计算的结果。consttype=typeofchildren;if(type==='undefined'||type==='boolean'){//以上所有内容都被视为null。children=null;}也就是说这里的children,是jsx计算的结果。示例如下://Renderablevalue1&&//=>jsx计算结果为,所以render"astring"&&//=>jsx计算结果是,所以渲染0&&//=>jsx计算为0,渲染'0'true&&//=>jsx计算为,sorender//non-renderablevaluefalse&&//=>jsx求值为false,所以什么都不渲染null&&//=>jsx求值为null,因此什么都没有Nonerenderundefined&&//=>jsx计算结果是未定义的,所以没有渲染。原因总结其实根本不是React渲染什么的问题,而是&&运算符后返回值的问题。因此,最根本的原因是React渲染了字符串、数字和普通组件。React不渲染undefined,boolean,null{"1"}//渲染为"1"{0}//渲染为0{}//假设是普通组件,渲染为{undefined}//不渲染{true}//不渲染{false}//不渲染{null}//不渲染源代码realhammerconsttype=typeofchildren;//React不会呈现未定义的布尔值if(type==='undefined'||type==='boolean'){//以上所有内容都被视为null。孩子=空;}让invokeCallback=false;if(children===null){invokeCallback=true;}else{switch(type){case'string':case'number'://React渲染字符串,数字invokeCallback=true;休息;case'object'://React渲染普通组件switch((children:any).$$typeof){caseREACT_ELEMENT_TYPE:caseREACT_PORTAL_TYPE:invokeCallback=true;}}}原值为null,undefined和boolean最终处理为null,而React并没有渲染null的源码锤子呢?渲染(孩子:ReactNode|null,上下文:对象,parentNamespace:string,):string{if(typeofchild==='string'||typeofchild==='number'){consttext=''+child;if(text===''){返回'';}this.previousWasTextNode=true;返回escapeTextForBrowser(文本);}else{让nextChild;({child:nextChild,context}=resolve(child,context,this.threadID));//React不会渲染nullif(nextChild===null||nextChild===false){return'';}对于渲染空字符串的html标签,会渲染空字符串,比如
""
会被渲染成
""
但是对于react来说,完整的过程是{null}=>{""}=>nothing例如,以下内容:
{''}
//=>
{''}
//=>
那么,React是如何处理空字符串的呢?exportfunctionpushTextInstance(target:Array
,text:string,responseState:ResponseState,):void{if(text===''){//空文本做没有DOM节点表示并且hydration知道这一点。//这个注释的意思是:空文本节点没有DOM节点表示,属于textNode返回;}//TODO:避免在常见情况下添加文本分隔符。target.push(stringToChunk(encodeHTMLTextNode(text)),textSeparator);}从源码中我们可以看到,对于一个空的文本节点,React会直接返回并且不会生成文本实例(TextInstance)。期待与你交流,共同进步:微信公众号:大前端/excellent_developers前端问答互助星球:t.zsxq.com/yBA2Biq