日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
能把隊友氣死的八種代碼(React版)

前幾天在前端技術群里聊起Code Review的事,大伙兒似乎都憋了一肚子氣:

站在用戶的角度思考問題,與客戶深入溝通,找到絳縣網站設計與絳縣網站推廣的解決方案,憑借多年的經驗,讓設計與互聯網技術結合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網站建設、網站制作、企業(yè)官網、英文網站、手機端網站、網站推廣、空間域名、虛擬主機、企業(yè)郵箱。業(yè)務覆蓋絳縣地區(qū)。

圖片

我覺得這份難言之隱應該要讓更多人看到,就跟Henry約了個稿:

圖片

于是Henry趕在周末,一邊帶娃,一邊給我抹眼淚整理(脫敏)出了這篇小小的屎山合集,供大家品鑒。

以下是正文。

1. 直接操作DOM

const a = document.querySelector('.a');

const scrollListener = throttle(() => {
  const currentY = window.scrollY;

  if (currentY > 100) {
    a.classList.add('show');
  } else {
    a.classList.remove('show');
  }
}, 300);

window.addEventListener('scroll', scrollListener);
return () => {
  window.removeEventListener('scroll', scrollListener);
};

上面的代碼在監(jiān)聽scroll方法的回調函數中,直接上手修改DOM的類名。眾所周知,React屬于響應式編程,大部份情況都不需要直接操作DOM,具體原因參考官方文檔(https://react.dev/learn/manipulating-the-dom-with-refs)。

優(yōu)化方法也很簡單,充分發(fā)揮響應式編程的優(yōu)點,用變量代替即可:

const [refreshStatus, setRefreshStatus] = useState('');

const scrollListener = throttle(() => {
  if (tab.getBoundingClientRect().top < topH) {
    setRefreshStatus('show');
  } else {
    setRefreshStatus('');
  }
}, 300);

return 
;

2. useEffect不指定依賴

依賴參數缺失。

useEffect(() => {
    console.log('no deps=====')
    // code...
});

這樣的話,每次頁面有重渲染,該useEffect都會執(zhí)行,帶來嚴重的性能問題。

例如我們項目中,這個useEffect內部執(zhí)行的是第一點中的內容,即每次都會綁定一個scroll事件的回調,而且頁面中有實時輪詢接口每隔5s刷新一次列表,用戶在該頁面稍加停留,就會有卡頓問題出現。

解決方案很簡單,根據useEffect的回調函數內容可知,如果需要在第一次渲染之后掛載一個scroll的回調函數,那么就給useEffect第二個參數傳入空數組即可,參考官方文檔(https://react.dev/reference/react/useEffect#useeffect)。

useEffect(() => {
    // code...
}, []);

3. 硬編碼

硬編碼,即一些數據信息或配置信息直接寫死在邏輯代碼中,例如

這兩行代碼本意是從url上拿到指定的參數的值,如果沒有,會用一個固定的配置做兜底。

乍一看代碼邏輯很清晰,但再想深一層,兜底值具體的含義是什么?為什么要用這兩個值來兜底?寫這行代碼的同學可能很快可以解答,但是一段時間之后,寫代碼的人和提需求的人都找不到了呢?

這個示例代碼還比較簡單,拿對應的值去后臺可以找到對應的含義,如果是寫死的是枚舉值,而且還沒有類型定義,那代碼就很難維護了。

圖片

解決此類問題,要么將這些內容配置化,即寫到一個config文件中,使用清晰的語義化命名變量;要么,至少在硬編碼的地方寫上注釋,交代清楚這里需要硬編碼的前因后果。

沐灑:

關于硬編碼問題,我在之前的一篇關于“配置管理”的文章里有詳細闡述和應對方案,感興趣的朋友可以看看《小白也能做出滿分前端工程:01 配置管理》

4. 放任文件長度,只著眼于當下的需求

很多同學做需求、寫代碼都比較少從全局考慮,只關注到當前需求如何完成。從“戰(zhàn)術”上來說沒有問題,快速完成產品的需求、快速迭代產品也是大家希望看到的。

可一旦只關注“戰(zhàn)術實現”而忽略“戰(zhàn)略設計”,除非做的產品是月拋型的,否則一定會遇到舊邏輯難以修改的情況。

如果再加上一個文件被多達10余人修改過的情況,那么每改一行代碼都會是一場災難,例如最近接手的一個頁面:

圖片

單文件高達1600多行!哪怕去除300多行的注釋,和300多行的模板,剩下的邏輯代碼也有1000行左右,這種代碼可讀性就極其糟糕,必須進行拆分。

而很常見的是,由于每一任經手人都疏于考慮全局,導致大量代碼毫無模塊化可言,甚至出現多個useEffect的依賴是完全相同的:

圖片

這里明顯還有另一個問題:濫用hooks。

從行號可以看出來確實是相同的依賴寫了多個useEffect,很明顯是多個同學各寫各的的需求引入的這些hooks。

這代碼跑肯定是能跑的,但是很可能會出現多個hooks中修改同一個變量,導致其他地方在使用的時候需要搞一些很tricky的操作來修Bug。

5.變量無初始值

在typescript的加持下,對變量的類型定義可以說是日益嚴格了。可是在一些變量的類型定義比較復雜的情況下,可能一個變量的字段很多、層級很復雜,此時有些同學就可能想偷個懶了,例如:

const [variable, setVariable] = useState();

// some code...
const queryData = function() {
    // some logic
    setVariable({ show: true });
};

useEffect(() => {
    queryData();
}, []);

return variable.show ?  : null;

這里的問題很明顯,如果queryData耗時比較長,在第一次渲染的時候,最后一行的variable.show就會報錯了,因為variable的初始值是undefined。所以聲明變量時,一定要根據變量的類型設置好有效默認值。

6. 三元選擇符嵌套使用

網上很多人會推薦說用三元選擇符代替簡單的if-else,但幾乎沒有見過有人提到嵌套使用三元選擇符的事情,如果看到如下代碼,不知道各位讀者會作何感想?

{condition1 === 1
    ? "數據加載中"
    : condition2
    ? "沒有更多了"
    : condition3
    ? "當前沒有可用房間"
    : "數據加載中"}

真的很難理解,明明只是一個簡單的提示語句的判斷,卻需要拿出分析性能的精力去理解,多少有點得不償失了。

這還只是一種比較簡單的三元選擇符的嵌套,因為當各個條件分支都為true時,就直接返回了,沒有做更多的判斷,如果再多做一層,都會直接把人的cpu的干爆炸了。 

替代方案: 

  1. 直接用if-else,可讀性更高,以后如果要加邏輯也很方便。
  2. Early Return,也叫衛(wèi)語句,這種寫法能有效簡化邏輯,增加可讀性。
if (condition1 === 1) return "數據加載中";
if (condition2) return "沒有更多了";
if (condition3) return "當前沒有可用房間";
return "數據加載中";

雖然不嵌套的三元選擇符很簡單,但是在例如jsx的模版中,仍然不建議大量使用三元選擇符,因為可能會出現如下代碼:

return (
    condition1 ? (
        
{condition3 ? "111" : "222"} {condition4 ? ( ) : null
) : ( {condition6 ? children1 : children2} ) )

類似的代碼在我們的項目中頻繁出現,模版中大量的三元選擇符導致文件內容拉得很長,很容易看著看著就不記得自己在哪個邏輯分支上了。

像這種簡單的三元選擇符,做成一個簡單的memo變量,哪怕是在組件內直接寫變量定義(例如:const clsName = condition2 ? cls1 : cls2),最終到模板的可讀性也會比上述代碼高。

7. 邏輯不拆分

React hooks可以很方便地幫助開發(fā)者聚合邏輯抽離成自定義hooks,千萬不要把一個頁面所有的useState、useEffect等全都放在一個文件中:

圖片

其實從功能上可以對頁面進行拆分,拆分之后這些變量的定義也就可以拆出去了。

其中有一個很簡單的原則就是,如果一個邏輯同時涉及到了useState和useEffect,那么就可以一并抽離出去成為一個自定義hooks。

例如接口請求大家一般都是直接在業(yè)務邏輯中做:

const Comp = () => {
    const [data, setData] = useState({});
    const [loading, setLoading] = useState(false);
    
    useEffect(() => {
        setLoading(true);
        queryData()
            .then((response) => {
                setData(response);
            })
            .catch((error) => {
                console.error(error);
            })
            .finally(() => {
                setLoading(false);
            });
    });
    
    if (loading) return "loading...";
    
    return 
{data.text}
; }

根據上面的原則,和數據拉取相關的內容涉及到了useState和useEffect,這整塊邏輯就可以拆出去,那么最終就只剩下:

const Comp = () => {
    const { data, loading } = useQueryData();
    
    if (loading) return "loading...";
    
    return 
{data.text}
; };

這樣下來,Comp組件就變得身份清爽了。

大家可以參考阿里的ahooks庫,里面收集了很多前端常用的hooks,可以極大提升開發(fā)效率和減少重復代碼。

8. 隨意讀取window對象的值

作為大型項目,很容易需要依賴別的模板掛載到window對象的內容,讀取的時候需要考慮到是否有可能拿不到window對象上的內容,從而導致js報錯?例如:

window.tmeXXX.a.func();

如果這個tmeXXX所在的js加載失敗了,或者是某個版本中沒有a這個屬性或者func這個函數,那么頁面就會白屏。

本文轉載自微信公眾號「沐灑」,作者「ASCII26」,可以通過以下二維碼關注。


新聞名稱:能把隊友氣死的八種代碼(React版)
標題網址:http://m.5511xx.com/article/dhgecge.html