React?classnames原理及測試用例
前言
本期的源碼閱讀任務(wù)是:
- 學(xué)會 classnames 的用法
- 學(xué)會 classnames 的原理
- 測試用例的使用
classnames 的用法
Classname 是一個 JavaScript 庫,它允許您有條件地將類名連接在一起。在構(gòu)建 React 組件或需要根據(jù)某些條件動態(tài)生成類名時,它可能非常有用。
下面是一個如何使用 classnames 的例子:
import classnames from 'classnames';
const Button = ({ primary, size }) => {
const classes = classnames('btn', {
'btn-primary': primary,
'btn-large': size === 'large',
'btn-small': size === 'small',
});
return <button className={classes}>Click me</button>;
};
在上面的示例中,classnames 函數(shù)接受一個類名和一個將類名映射為布爾值的對象。如果給定類名的布爾值為 true,則該類名將包含在類名的最終列表中。如果值為 false,則不包括類名。
還可以將一個字符串作為第二個參數(shù)傳遞給類名,在這種情況下,如果值為 true,那么它將被添加到類名的最終列表中。
const classes = classnames('btn', primary && 'btn-primary');
學(xué)會 classnames 的原理
classnames 源碼并不復(fù)雜,除去一些兼容性判斷,主要功能實現(xiàn)的代碼如下:
function classNames() {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === "string" || argType === "number") {
classes.push(arg);
} else if (Array.isArray(arg)) {
if (arg.length) {
var inner = classNames.apply(null, arg);
if (inner) {
classes.push(inner);
}
}
} else if (argType === "object") {
if (
arg.toString !== Object.prototype.toString &&
!arg.toString.toString().includes("[native code]")
) {
classes.push(arg.toString());
continue;
}
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
}
}
return classes.join(" ");
}
主要工作原理如下:
- 函數(shù)聲明了一個名為
class的空數(shù)組,該數(shù)組將用于存儲生成的類名。 - 然后,函數(shù)進入一個循環(huán),循環(huán)遍歷傳遞給函數(shù)的參數(shù)。對于每個參數(shù),執(zhí)行以下步驟:
- 檢查參數(shù)的類型。如果它是一個字符串或數(shù)字,添加到類數(shù)組。
- 如果參數(shù)是數(shù)組,則函數(shù)檢查它是否為非空。如果是,則函數(shù)以數(shù)組元素作為參數(shù)遞歸地調(diào)用自身,并將結(jié)果添加到類數(shù)組中。
- 如果參數(shù)是一個對象,那么函數(shù)將檢查它是否有一個
toString方法,該方法不是本機Object.Prototype.toString方法。如果是這樣,調(diào)用oString的結(jié)果將添加到類數(shù)組中。如果不是,函數(shù)將遍歷對象自己的可枚舉屬性,并將屬性名稱添加到類數(shù)組中(如果它們的對應(yīng)值為真)。 - 循環(huán)結(jié)束后,將類數(shù)組合并到一個單獨的字符串中,使用一個空格字符作為分隔符,并返回結(jié)果字符串。
測試用例的使用
className 庫使用 Mocha 進行代碼測試:
Mocha 是一個運行在 Node.js 和瀏覽器上的 JavaScript 測試框架。它用于編寫和運行 JavaScript 代碼的測試用例。
使用 Mocha 寫測試用例的簡單示例:
const assert = require("assert");
describe("myFunction", () => {
it("should return the expected result", () => {
assert.equal(myFunction(1, 2), 3);
});
});
- it 函數(shù)用于定義單個測試用例。
- 斷言模塊用于驗證函數(shù)是否返回預(yù)期的結(jié)果。
一些測試用例
describe('classNames', function () {
// 測試能夠識別具有真值得對象
it('keeps object keys with truthy values', function () {
assert.equal(classNames({
a: true,
b: false,
c: 0,
d: null,
e: undefined,
f: 1
}), 'a f');
});
// 檢查 classNames 函數(shù)是否正確地處理了其輸入?yún)?shù)中的假值,并且只在生成的類名字符串中包含真值。
it('joins arrays of class names and ignore falsy values', function () {
assert.equal(classNames('a', 0, null, undefined, true, 1, 'b'), 'a 1 b');
});
// 這個測試用例檢查 classNames 函數(shù)是否正確地處理了各種不同類型的參數(shù)
it('supports heterogenous arguments', function () {
assert.equal(classNames({a: true}, 'b', 0), 'a b');
});
// 這個測試用例檢查 classNames 函數(shù)是否正確地從生成的類名字符串中刪除了前導(dǎo)空格和尾隨空格。
it('should be trimmed', function () {
assert.equal(classNames('', 'b', {}, ''), 'b');
});
// 這個測試用例檢查 classNames 函數(shù)在調(diào)用時是否返回一個空字符串,該函數(shù)的唯一參數(shù)是一個空對象。
it('returns an empty string for an empty configuration', function () {
assert.equal(classNames({}), '');
});
// ... 省略部分測試用例
});
總結(jié)
Classname 非常有用,它能夠根據(jù)應(yīng)用程序的狀態(tài)構(gòu)建動態(tài)類名。避免編寫冗長和重復(fù)的 if-else 語句來構(gòu)建類名。同時,源碼測試用例寫得非常詳盡,很有借鑒意義,可以用來參考給自己的代碼寫一些測試用例。
以上就是React classnames原理及測試用例的詳細(xì)內(nèi)容,更多關(guān)于React classnames測試用例的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決React報錯Expected an assignment or funct
這篇文章主要為大家介紹了React報錯Expected an assignment or function call and instead saw an expression解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
ReactNative踩坑之配置調(diào)試端口的解決方法
本篇文章主要介紹了ReactNative踩坑之配置調(diào)試端口的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
解決React報錯Property does not exist on 
這篇文章主要為大家介紹了React報錯Property does not exist on type 'JSX.IntrinsicElements'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12

