2017-03-07 42 views
4

是否可以使用Rect.PropTypes來強制數組的長度?具有特定長度的React.PropTypes數組

這是一個非常簡單的例子:剛對象,因此我想這

const TWO_NUMBERS = PropTypes.array; // i need this to be an array of two numbers 

我知道在JavaScript的數組是:

const TWO_NUMBERS = PropTypes.shape({ 
    0: PropTypes.number.isRequired, 
    1: PropTypes.number.isRequired, 
}); 

然而,這一直告訴警告我expected an object but got an array

回答

6

在這種情況下,您需要編寫自己的特殊的PropTypes函數,該函數提供您要做的反應。如果TWO_NUMBERS不是數組,是不是兩個數組,而不僅是一個整數數組

const TWO_NUMBERS = function(props, propName, componentName) { 
    if (!Array.isArray(props.TWO_NUMBERS) || props.TWO_NUMBERS.length != 2 || !props.TWO_NUMBERS.every(Number.isInteger)) { 
    return new Error(`${propName} needs to be an array of two numbers`); 
    } 

    return null 
} 

這將拋出一個錯誤。在這個例子塊底部

https://facebook.github.io/react/docs/typechecking-with-proptypes.html#react.proptypes

其:

,你可以獲取此proptype功能的信息。

+0

非常感謝你finalfreq!我是新來的proptypes,我絕對喜歡這個! – Noitidart

-4

PropTypes檢查不屬於屬性的類型。此外,在生產模式下禁用檢查PropTypes。這使得PropTypes無法在運行時檢查數組長度的變化。

3

自定義函數在這裏是正確的方法。

const propTypes = { 
    TWO_NUMBERS: arrayOfLength.bind(null, 1), 
    } 

    const arrayOfLength = function(expectedLength, props, propName, componentName) { 
    const arrayPropLength = props[propName].length 

    if (arrayPropLength !== expectedLength) { 
     return new Error(
     `Invalid array length ${arrayPropLength} (expected ${expectedLength}) for prop ${propName} supplied to ${componentName}. Validation failed.` 
    ); 
    } 
    }, 
+0

比你非常Garrett!首先,我接受了最終的解決方案。 :( – Noitidart

+1

完全理解!讓我的答案採取任何數組長度規範,所以它有點可重複使用(不只是複製以前的答案),所以希望這會有所幫助! – garrettmaring

+0

它太多了!我真的很感激它的兄弟!尤其是編輯! – Noitidart

1

受@finalfreq的回答啓發,我想出了這個。它處理兩個數字(在這種情況下爲浮點數),也可以用作arrayOf(twoNumbers)。不知道如何使它像twoNumbers.isRequired還沒有...

此外,我認爲如果你不在驗證比較中使用否定,我認爲代碼更清潔,更容易遵循。

import invariant from 'invariant'; 

function isValid(value) { 
    return Array.isArray(value) && value.length === 2 && value.every(Number.isFinite); 
} 

export default function twoNumbers(props, propName, componentName) { 
    if (Array.isArray(props)) { 
    props.forEach((item, index) => { 
     invariant(
     isValid(item), 
     `Array item index ${index} is ${item}, but needs to be an array of two numbers` 
    ); 
    }); 
    } 

    const value = props[propName]; 

    if (!value) return; // not required so could be null 

    invariant(isValid(value), `${componentName} ${propName} needs to be an array of two numbers`); 
} 
+0

Thanks @Thijs for sharing!我現在實際上使用流式類型,並且得到類似的情況。 – Noitidart

相關問題