最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 为什么 react-hook 函数不允许在if中使用,要按顺序写

    正文概述 掘金(小金人)   2020-12-18   3166

    随着 react-hook 正式发布,大家一夜之间都爱上了这个小家伙。useState, useEffect, useMemo ... 大家体验了它们的姿势之后,都深表喜欢。极大的减少了组件的代码量,让组件看起来干净整洁。但使用时想必大家都出现了疑惑为什么这些函数要按顺序写。比如以下代码是不被允许的。

    let value = true;
    const App = (props) => {
        if(value) {
          const [v,setV] = useState('v');
        }else {
          const [t,setT] = useState('t');
        }
        return <div>这是不被允许的</div>;
    };
    
    

    接下来我就通过编写一个阉割版 useState 函数的方法来为大家解答这个问题。 首先我们编写一个简单的渲染函数,一旦调用这个函数组件进行重渲染。( 这只是使用了最简单粗暴的方法进行重渲染,真实的渲染环境较为复杂), stateIndex会在下文讲解。

    const reRender = () => {
      stateIndex = -1 
      ReactDOM.render(<App/>,document.getElementById('root'))
    }
    
    

    下面我们在来简单实现一下 useState 。

    let stateQueue = []; // 用于存放每个useState返回值。
    let stateIndex = -1;  //给每个 useState的返回值一个序号。
    function useState(initState) {
      stateIndex++;
      stateQueue[stateIndex] = stateQueue[stateIndex] || initState;
      const currentIndex = stateIndex
      function setState(newState) {
        stateQueue[currentIndex] = newState;
        reRender(); //组件重渲染
      }
      return [stateQueue[stateIndex],setState]
    }
    

    从这可以看出每次调用一次 useState, stateQueue 就会存储一个值,比如你在App组件中使用 [v,setV] = useState('v'),那么 stateQueue[0] 的值会变为 'v',其次stateIndex会加1。 再次调用 [t, setT] = useState('t') stateQueue[1]的值会是't',以此类推。

    在看看 setState , 假如你在此时调用setV('v1'),那么由于闭包的原因将会执行stateQueue[0] = 'v1',从而改变 stateQueue[0] 的值,接下来也是最关键的一步,reRender 被调用,stateIndex重新变为-1,App组件重渲染, [v,setV] = useState('v')将会再次被调用,但此时将会调用stateQueue[0] || iniState而他现在的返回值为 'v1', 变量 v 的值也就会等于 v1 渲染在页面上。这也就是 useState 的大致处理过程。

    此时在来回答最开始的问题, 为什么最开始的那个案例是不被允许的。想象一下假如最开始那个 value的值是 true,那么他会让 变量 v = stateQueue[0] = 'v' , 此时再调用 setV('v1') ,页面重渲染,如果此时 value 的值是 false, 那么他会让 变量 t = stateQueue[0] = 'v1' ,这显然不是我们想看见的。所以 react-hook 为了杜绝这种事情发生,不允许 hook 函数在 if 语句中使用。


    起源地下载网 » 为什么 react-hook 函数不允许在if中使用,要按顺序写

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元