programing

React에 필요한 프로포즈를 1개 이상 포함

testmans 2023. 3. 31. 21:55
반응형

React에 필요한 프로포즈를 1개 이상 포함

최소한 필요한 소품 중 하나를 만들어야 합니다.

MyComponent.propTypes = {
   data: PropTypes.object,
   url: PropTypes.string
};

따라서 위의 예에서는 다음 중 하나를 수행합니다.data또는url소품을 제공해야 합니다.여기서의 사용 사례는 사용자가 다음 중 하나를 제공할 수 있다는 것입니다.data또는url. 만약url컴포넌트가 제공되면 이 컴포넌트가 이 컴포넌트를 가져옵니다.data.

보너스 질문:소품 하나와 소품 하나를 어떻게 해야 하나요?

PropTypes는 실제로 커스텀 함수를 인수로 사용할 수 있으므로 다음과 같은 작업을 수행할 수 있습니다.

MyComponent.propTypes = {
  data: (props, propName, componentName) => {
    if (!props.data && !props.url) {
      return new Error(`One of props 'data' or 'url' was not specified in '${componentName}'.`);
    }
  },

  url: (props, propName, componentName) => {
    if (!props.data && !props.url) {
      return new Error(`One of props 'url' or 'data' was not specified in '${componentName}'.`);
    }
  }
}

에러 메세지가 표시됩니다.이 메서드를 사용하는 경우 null 또는 오류만 반환할 수 있습니다.

자세한 내용은 이쪽에서 확인하실 수 있습니다.

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

react docs:

// 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(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

@finalfreq 솔루션의 보다 간결한 버전:

const requiredPropsCheck = (props, propName, componentName) => {
  if (!props.data && !props.url) {
    return new Error(`One of 'data' or 'url' is required by '${componentName}' component.`)
  }
}

Markdown.propTypes = {
  data: requiredPropsCheck,
  url: requiredPropsCheck,
}

finalfreq 답변과 그에 대한 kousa 코멘트 추가.

아이콘이나 제목을 필요로 하는 버튼 컴포넌트가 있었습니다.위의 답변과 같은 것이 적어도1개 존재하는지 확인합니다.체크 후 타입을 다음과 같이 검증할 수 있습니다.

Button.propTypes = {
  icon: (props, propName, componentName) => {
    if (!props.icon && !props.title) {
      return new Error(`One of props 'icon' or 'title' was not specified in '${componentName}'.`)
    }
    if (props.icon) {
      PropTypes.checkPropTypes({
        icon: PropTypes.string, // or any other PropTypes you want
      },
      { icon: props.icon },
      'prop',
      'PrimaryButtonWithoutTheme')
    }
    return null
  }
  title: // same process
}

에 대한 자세한 내용을 참조해 주세요.PropTypes.checkPropTypes여기서 읽다

저는 같은 문제를 재사용할 수 있는 방법으로 해결하기 위해 이 도우미를 썼습니다.propType 함수처럼 사용할 수 있습니다.

MyComponent.propTypes = {
  normalProp: PropType.string.isRequired,

  foo: requireOneOf({
    foo: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.number
    ]),
    bar: PropTypes.string,
  }, true),
};

이 예에서는 foo 또는 bar 중 하나가 My Component 소품 안에 있는지 확인합니다.두 번째 인수를 생략하면 foo 또는 bar 중 하나만 통과됩니다.

/**
 * Takes a propTypes object ensuring that at least one of the passed types
 * exists on the component.
 *
 * Usage:
 *
 * MyComponent.propTypes = {
 *   normalProp: PropType.string.isRequired,
 *
 *   foo: requireOneOf({
 *     foo: PropTypes.oneOfType([
 *       PropTypes.string,
 *       PropTypes.number
 *     ]),
 *     bar: PropTypes.string,
 *   }, true),
 * };
 *
 * @param requiredProps object
 * @param allowMultiple bool = false  If true multiple props may be
 *                                    passed to the component
 * @return {Function(props, propName, componentName, location)}
 */
export const requireOneOf = (requiredProps, allowMultiple = false) => {
  return (props, propName, componentName, location) => {
    let found = false;

    for (let requiredPropName in requiredProps) {
      if (requiredProps.hasOwnProperty(requiredPropName)) {
        // Does the prop exist?
        if (props[requiredPropName] !== undefined) {
          if (!allowMultiple && found) {
            return new Error(
              `Props ${found} and ${requiredPropName} were both passed to ${componentName}`
            );
          }

          const singleRequiredProp = {};
          singleRequiredProp[requiredPropName] = requiredProps[requiredPropName];
          const singleProp = {};
          singleProp[requiredPropName] = props[requiredPropName];

          // Does the prop match the type?
          try {
            PropTypes.checkPropTypes(singleRequiredProp, singleProp, location, componentName);
          } catch (e) {
            return e;
          }
          found = requiredPropName;
        }
      }
    }

    if (found === false) {
      const propNames = Object.keys(requiredProps).join('", "');
      return new Error(
        `One of "${propNames}" is required in ${componentName}`
      );
    }
  };
};

   
function requireALeastOne(checkProps) {
  return function(props, propName, compName) {
    const requirePropNames = Object.keys(checkProps);

    const found = requirePropNames.find((propRequired) => props[propRequired]);

    try {
      if (!found) {
        throw new Error(
          `One of ${requirePropNames.join(',')} is required by '${compName}' component.`,
        );
      }
      PropTypes.checkPropTypes(checkProps, props, propName, compName);
    } catch (e) {
      return e;
    }
    return null;
  };
}


const requireALeast = requireALeastOne({
  prop1: PropTypes.string,
  prop2: PropTypes.number
});

Comp.propTypes = {
  prop1: requireALeast,
  prop2: requireALeast
};

언급URL : https://stackoverflow.com/questions/42284076/at-least-one-required-prop-in-react

반응형