初始值取值问题导致切换页面会闪屏(React)

1,945 阅读1分钟

在做项目时发现,我的标签页面在每次点击进去的时候,会先跳转到删除标签后的页面,再跳回标签页。开始我以为时路由的问题,排查后不是,然后觉得是div的问题,排查后发现并没有影响。

这是出问题的页面:

 return (
    <Layout>
      <Topbar>
        <Icon name="left" onClick = {onClickBack}/>
        <span>编辑标签页</span>
        <span> </span>
      </Topbar>
      {tag ? tagContent(tag) : <Center><IconWrapper><Icon name="crying"/></IconWrapper>tag 不存在</Center>}
    </Layout>
  )

最后锁定就在判断tag是否存在这里出了问题,log出刚进页面的时候,tag是不存在的,然后又存在,tag为什么会不存在呢?

到我封装的自定义hook里面发现我的tags初始值是空,在一进入这个页面就会渲染一次,这时候的tags是空,在运行到effect时,会从localStorage里取出tags,然后再次渲染就会导致我的第一次对tag的判断就是空。

体现在页面就是闪屏了

出问题的代码:

const useTags =() =>{//封装一个自定义hook
  const [tags,setTags] = useState<{id:number ; name:string}[]>([]);
  useEffect(()=>{
    let localTags = JSON.parse(window.localStorage.getItem('tags') || '[]')
    if (localTags.length ===0){
      localTags = [
        {id:createId(),name:'衣服'},
        {id:createId(),name:'吃饭饭'},
        {id:createId(),name:'家庭消费'},
        {id:createId(),name:'粗去玩~'},
      ]
    }
    setTags(localTags);
  },[]);//deps是空数组代表第一次进来就执行

改了以后的代码:

const useTags =() =>{//封装一个自定义hook
  let localTags = JSON.parse(window.localStorage.getItem('tags') || '[]');
  const [tags,setTags] = useState<{id:number ; name:string}[]>(localTags);
  useEffect(()=>{
    //let localTags = JSON.parse(window.localStorage.getItem('tags') || '[]')
    if (localTags.length ===0){
      localTags = [
        {id:createId(),name:'衣服'},
        {id:createId(),name:'吃饭饭'},
        {id:createId(),name:'家庭消费'},
        {id:createId(),name:'粗去玩~'},
      ]

    }
    setTags(localTags);
  },[]);//deps是空数组代表第一次进来就执行

就是将初始值变为我在localStorage里面取到到的tags,这样我在删除tag之前判断tag是否存在的时候也不会是空!

const [tags,setTags] = useState<{id:number ; name:string}[]>(localTags);

又是一个小bug,可是也是让人绞尽脑汁了!