2016-09-14 1 views
0

나는 React를위한 사용자 정의 "튜플"prop-type을 만들려고 노력하고 있지만, 나는 약간의 장애물에 부딪쳤다.터플 소품 유형 검사기를 만드는 방법은 무엇입니까?

API는 다음과 같을 것이다 :

import {PropTypes} from 'react'; 

export default class MyComponent extends React.Component { 

    static propTypes = { 
     myProp: tuple(PropTypes.number, PropTypes.string), 
    }; 

myProp 첫번째 요소가 다수 존재하여, 2 소자 어레이인지 확인 것이고, 두 번째는 문자열 인.

여기에 내가 가진 얼마나 멀리입니다 :

export function tuple(...arrayOfTypeCheckers) { 
    return requirable(function(props, propName, componentName) { 
     let value = props[propName]; 
     if(!Array.isArray(value)) { 
      throw new Error(`Expected array for \`${propName}\` in \`${componentName}\``); 
     } 
     if(value.length !== arrayOfTypeCheckers.length) { 
      throw new Error(`\`${propName}\` must have exactly ${arrayOfTypeCheckers.length} elements in \`${componentName}\`, got ${value.length}`); 
     } 
     for(let i = 0; i < value.length; ++i) { 
      let checker = arrayOfTypeCheckers[i]; 

      if(!__NEED_HELP_HERE__) { 
       throw new Error(`${propName}[${i}] is not of the expected type in \`${componentName}\``) 
      } 
     } 

     return null; 
    }); 
} 

(requirable의 구현이 here을 찾을 수 있습니다)

을 그러나, 나는 __NEED_HELP_HERE__을 구현하는 방법을 알아낼 수 없습니다. PropTypes.string

function(props, propName, componentName) 

당신은 소품의 전체 객체 플러스 PROPNAME 소요 알 수 있습니다, 서명과 다른 소품 형이다. 값은 다음과 같이 액세스됩니다.

var propValue = props[propName]; 

즉, 배열에서 고유 한 값을 제공 할 수 없습니다.

어떻게하면 React의 PropTypes.xyz 검사기를 호출 할 수 있습니까?

답변

0

React의 내부 API를 활용하기가 너무 어려워서 어쨌든 not to을 말하고 있으므로 유형 검사기를 직접 구현해야했습니다. 그들은 값을 true 또는 false를 반환 단지 기능이있어,

const lo = require('lodash'); 

function tuple(...types) { 
    return requirable(function(props, propName, componentName, location, propFullName) { 
     let value = props[propName]; 
     if(!location) { 
      location = 'prop'; 
     } 
     if(!propFullName) { 
      propFullName = propName; 
     } 

     if(!Array.isArray(value)) { 
      throw new Error(`Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`, expected ${types.length}-element array`); 
     } 
     if(value.length !== types.length) { 
      throw new Error(`Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`, expected ${types.length}-element array, got array of length ${value.length}`); 
     } 
     for(let i = 0; i < value.length; ++i) { 
      if(!types[i](value[i])) { 
       throw new Error(`Invalid ${location} ${propFullName}[${i}] supplied to \`${componentName}\`, unexpected type`) 
      } 
     } 

     return null; 
    }); 
} 

function requirable(predicate) { 
    const propType = (props, propName, ...rest) => { 
     // don't do any validation if empty 
     if(props[propName] === undefined) { 
      return; 
     } 

     return predicate(props, propName, ...rest); 
    }; 

    propType.isRequired = (props, propName, componentName, ...rest) => { 
     // warn if empty 
     if(props[propName] === undefined) { 
      return new Error(`Required prop \`${propName}\` was not specified in \`${componentName}\`.`); 
     } 

     return predicate(props, propName, componentName, ...rest); 
    }; 

    return propType; 
} 

const TypeCheckers = { 
    TypedArray: lo.isTypedArray, 
    Object: lo.isObject, 
    PlainObject: lo.isPlainObject, 
    RegExp: lo.isRegExp, 
    String: lo.isString, 
    Undefined: lo.isUndefined, 
    Number: lo.isNumber, 
    Null: lo.isNull, 
    NativeFunction: lo.isNative, 
    Function: lo.isFunction, 
    Error: lo.isError, 
    FiniteNumber: lo.isFinite, 
    NaN: lo.isNaN, 
    DomElement: lo.isElement, 
    Date: lo.isDate, 
    Array: lo.isArray, 
    Boolean: lo.isBoolean, 
    Stringable: obj => obj && lo.isFunction(obj.toString), 
}; 

은 "유형"실제 유형되지 않습니다

여기에 코드입니다. lodash에서 일부 도우미 기능을 사용하고 있습니다. React에서 추출한 것보다 훨씬 쉽기 때문입니다. 그러나 무엇이든 사용할 수 있습니다.

여전히 내부 API를 사용하여 propFullName을 얻지 만,이를 제거하기위한 대비책을 넣습니다. 오류 메시지는 전체 소품 이름 없이는 정말 끔찍해 보입니다. 예 :

경고 : 소품 유형 실패 : 잘못된 소품 0 [1] PhsaDocToolbar에 공급, 예상치 못한 유형을

그러나 propFullName로 우리가 얻을 :

경고 : 실패 소품 종류 : 잘못된 소품 docTypes [0] [1] PhsaDocToolbar (예상치 못한 유형)에 입력

PropTypes.arrayOf(tuple(TypeCheckers.Number, TypeCheckers.String))과 같은 것을 만듭니다.

+0

이 코드를'npm'을 통해 가져올 수있는 프로젝트로 게시 했습니까? – codermonkeyfuel

+0

@codermonkeyfuel 아니요, 죄송합니다. 이 함수들은 내가 게시하기 전에 좀 더 세련된 것이 필요하다. 아마 lodash에 대한 종속성을 제거 할 것이다. – mpen

관련 문제