2015-07-01 30 views
6

Üzerinde Birden çok Doğrulama React.PropTypes kullanarak tek bir prop üzerinde birden çok doğrulamaya sahip olmanın bir yolu var mı. Özellikle bir özel doğrulama ve bir hisse senedi doğrulamasını karıştırmak ister.React PropTypes

İki sahne var, bir nesne options ve bir dize value. Ben props.value bir dize değil, aynı zamanda nesnede bir anahtar olduğunu kontrol etmek istiyorum. bu büyük işleri

propTypes: 
    options: React.PropTypes.Object.isRequired 
    value: (props, propName, componentName) -> 
    unless props[propName] of props.options 
     new Error('my custom message') 

, ama aynı zamanda benim değeri bir dize türüdür sağlamak istiyoruz: Bu CoffeeScript kullanmak gibi görünüyor. Eminim ki, bu özelleştirme fonksiyonunda hiçbir doğrulama yapamazdım, ama ideal olarak, React.PropTypes.string.isRequired'u kullanmayı çok isterim. Ben sadece özel işlevine koyup onu çalıştırmayı denedim ama işe yaramadı. Aşağıdaki işe yaramadı ya:

value: React.PropTypes.string.isRequired && (props, propName, componentName) -> 
    unless props[propName] of props.options 
     new Error('my custom message') 

bu doğrulayıcıda inşa hızla reaksiyona girerek kullanarak çalışan, ya da benim işlevinde bunu yeniden tek seçeneği almanın bir yolu var mı? dokümanlarında Reusable Components sayfadan

cevap

2

:

You can also specify a custom validator. It should return an Error 
// object if the validation fails. Don't `console.warn` or throw, as this 
// won't work inside `oneOfType`. 
customProp: function(props, propName, componentName) { 
    if (!/matchme/.test(props[propName])) { 
    return new Error('Validation failed!'); 
    } 
} 

Yani PropType hiçbir şey veya bir hata nesnesi döndürür. İki propytip alan ve sonucu birleştiren bir 'all' fonksiyonu yazabiliriz.

const allPropTypes = (...types) => (...args) => { 
    const errors = types.map((type) => type(...args)).filter(Boolean); 

    // no errors? cool! 
    if (errors.length === 0) return; 

    // collect the messages and join them together 
    const message = errors.map((e) => e.message).join('\n'); 
    return new Error(message); 
}; 

Daha sonra birden fazla propTypes öğesine karşı gelmek için bunu kullanabilirsiniz.

propTypes = { 
    foo: allPropTypes(
    PropTypes.string.isRequired, 
    (props, propName, componentName) => props.options && props.options[props[propName]] 
     ? undefined 
     : new Error(
      `${componentName}: expected prop ${propName}="${prop[propName]}"` 
      + `to be a key of prop "options" ` 
      + `(one of ${Object.keys(props.options).join(', ')})` 
     ) 
) 
} 

Not: Bunlardan hiçbiri sınanmadı, ancak sözdizimi hatası yok! Es3'e babel ile derleyebilir veya elle CS'ye dönüştürebilirsiniz.

+0

Özel doğrulama işlemime bir şeyler eklemeye devam edebileceğimin farkındayım. muhtemelen [propName] == 'string' 'türünde bir yazım yapmadıkça yeni bir hata (' msg ') döndürerek yapabilirim, ancak tepki vermenin daha resmi bir yolunun olup olmadığını soruyorum (yani hala 'React.PropTypes.string.isRequired' işlevini kullanın. – PhilVarg

+0

@ PhilVarg'da neler olup bittiği ile ilgili daha belirgin olanı kendi proptipinizi oluşturmalısınız. İnşa edilen propTyp'ların hiçbiri bildiğim kadarıyla çapraz kontroller yapmaz. Bir yere bir modüle koyabilir ve güzel bir adla içe aktarabilir ve hatta 'options' bölümünün dinamik olmasına, örn. foo: isKeyOfProp ('seçenekler') '. – FakeRainBrigand

0

this bağlantısını izlerseniz, Ian Thomas, propTypes modülünün bir parçası olarak yanıt vermeyen ancak dışa aktarılmayan bir createChainableTypeChecker yönteminin kullanımını açıklar. Makale, zincir doğrulama çağrıları için aynı kodu nasıl kullanabileceğinizi açık bir şekilde açıklamaktadır:

function createChainableTypeChecker(validate) { 
    function checkType(isRequired, props, propName, componentName, location) { 
    componentName = componentName || ANONYMOUS; 
    if (props[propName] == null) { 
     var locationName = ReactPropTypeLocationNames[location]; 
     if (isRequired) { 
     return new Error(
      ("Required " + locationName + " `" + propName + "` was not specified in ") + 
      ("`" + componentName + "`.") 
     ); 
     } 
     return null; 
    } else { 
     return validate(props, propName, componentName, location); 
    } 
    } 

    var chainedCheckType = checkType.bind(null, false); 
    chainedCheckType.isRequired = checkType.bind(null, true); 

    return chainedCheckType; 
} 
+0

ReactPropTypeLocationNames'i nereden alabilirim? – Shanimal