最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 在 React 中如何防止代码爆炸

    正文概述 掘金(尖沙咀最强布拿拿)   2021-03-24   682

    在 React 中如何防止代码爆炸

    Functional Component 是很棒的东西

    在写了很长一段时间的 useState, useEffect 之后,发现 Functional Component 确实比 Class Component 更加方便,模糊了生命周期的概念,也没有很多令人上头 UNSAFE 方法。但是真正让我想要防止代码爆炸的其实是一条 lint 规则,就是一个方法不能超过 200 行。算上本身的逻辑代码,格式化之后的空行。其实很容易就写超过 200 行了,一个组件如果只有 200 行显然不怎么现实。如果说是要拆分子组件,在最外层组件也是会有很多 state 需要去维护,所以有一个地方肯定得爆炸。

    Scenario 1

    假设你有一个很简单的需求,就是写一个 Switch 用来控制一些简单的文字。

    那么你的代码最初可能会长成这样:

    import React, {useState} from 'react';
        
    const App = () => {
        const [state, setState] = useState('on');
    		return <div>
          	<div>State: {state}</div>
            <div>
                <button type="button" onClick={() => {
                    setState('on')
                }}>
                  Turn On
                </button>
                <button type="button" onClick={() => {
                    setState('off')
                }}>
                  Turn Off
                </button>
                <button type="button" onClick={() => {
                    state === '' ? setState('off') : setState('on')
                }}>
                  Toggle
                </button>
            </div>
       </div>  
    }
    

    Scenario 2

    实际上也不是不能被接受,因为这里逻辑其实并不复杂,稍微看一下也是非常简单明了的。那么接下来我们再改一个版本:

    import React, {useState, useCallback} from 'react';
    const App = () => {
        const [state, setState] = useState('on');
    
        const on = React.useCallback(() => {
            setState('on');
        }, []);
        const off = React.useCallback(() => {
            setState('off');
        }, []);
        const toggle = React.useCallback(() => {
            setState(s => (s === 'on' ? 'off' : 'on'));
        }, []);
        
        return <div>
            <div>State: {state}</div>
            <div>
                <button type="button" onClick={on}>
                  Turn On
                </button>
                <button type="button" onClick={off}>
                  Turn Off
                </button>
                <button type="button" onClick={toggle}>
                  Toggle
                </button>
            </div>
       </div>  
    }
    

    现在再来看一下,在 View 中代码显然变少了,也更好让人理解了。逻辑与视图分离了。

    much better, so far so good.

    Scenario 3

    接着,当一个新的需求提了出来之后,这里你需要一个输入框。

    const App = () => {
        const [state, setState] = useState('on');
        const [inputState, setInputState] = React.useState('');
    
        const on = React.useCallback(() => {
            setState('on')
        }, [])
        const off = React.useCallback(() => {
            setState('off')
        }, [])
        const toggle = React.useCallback(() => {
            setState(s => (s === 'on' ? 'off' : 'on'))
        }, []);
    
        const handleInputChange = React.useCallback(e => {
            setInputState(e.target.value)
        }, []);
    
        const resetInput = React.useCallback(() => {
            setInputState('')
        }, []);
    
        return <div>
            <div>State: {state}</div>
            <div>
                <button type="button" onClick={on}>
                  Turn On
                </button>
                <button type="button" onClick={off}>
                  Turn Off
                </button>
                <button type="button" onClick={toggle}>
                  Toggle
                </button>
            </div>
            <div>
                <label htmlFor="randomWord">Random Word</label>
                <input
                  type="text"
                  id="randomWord"
                  onChange={handleInputChange}
                  value={inputState}
                />
                <button type="button" onClick={resetInput}>
                  Reset Input
                </button>
          </div>
       </div>  
    }
    

    从上面来看,我新加入的代码并不多,无非是多了一个 useState,已经两个方法。但是这仅仅是一个 input 框而已,所以如果你在多一些这样的需求,这样的组件,你的代码就炸啦。因为这样带来了一些问题:

    • 你的方法以后离 useState 会很远,你需要来回滚动你的代码才能让你脑子记住
    • 这样子的代码带来了我之前提到的问题,很容易就爆炸了,超过行数的限制
    • 以后你的心智负担会很重,如果移除一些组件的时候,会遗漏一些方法或者 state

    解决方案 useCustomHook is the rescue

    import React, {useState, useMemo} from 'react';
    
    const useOnOff = () => {
        const [state, setState] = React.useState('off')
        const handlers = useMemo(() => ({
            on: () => {
                setState('on')
            },
            off: () => {
                setState('off')
            },
            toggle: () => {
                setState(s => (s === 'on' ? 'off' : 'on'))
            },
        }), []);
        return [state, handlers]
    }
    
    const useInput = () => {
      const [state, setState] = React.useState('')
    
      const handlers = React.useMemo(() => ({
            handleInputChange: e => {
                setState(e.target.value)
            },
            resetInput: () => {
                setState('')
            },
        }),[])
      return [state, handlers]
    }
    
    const App = () => {
        const [state, { on, off, toggle }] = useOnOff()
        const [inputState, { handleInputChange, resetInput }] = useInput()
    
        return <div>
            <div>State: {state}</div>
            <div>
                <button type="button" onClick={on}>
                  Turn On
                </button>
                <button type="button" onClick={off}>
                  Turn Off
                </button>
                <button type="button" onClick={toggle}>
                  Toggle
                </button>
            </div>
            <div>
                <label htmlFor="randomWord">Random Word</label>
                <input
                  type="text"
                  id="randomWord"
                  onChange={handleInputChange}
                  value={inputState}
                />
                <button type="button" onClick={resetInput}>
                  Reset Input
                </button>
          </div>
       </div>  
    }
    

    这样看起来是不是心智负担就少了很多很多!而且最重要的是,这两个 customHook 可以放到其他地方,以备不时之需,实际上 on off switch 这种在项目中是非常常见的,这样一来你就防止了代码爆炸了。

    这其实是一个软件工程的非常常见的现象,如果你的心智出现了负担,那么多一层封装可以解决你的问题,如果还有,那就再来一层。


    起源地下载网 » 在 React 中如何防止代码爆炸

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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