首页 > 解决方案 > 通过 props 将 PropTypes 值传递给有状态的 React 子组件

问题描述

我为传递给孩子的所有道具建立了我的 PropTypes on App 组件。

class App extends Component {
    constructor( props ) {
        super( props );

        this.state = {
            anyProps : undefined',
        };
    }

    propsValues = {
        anyProp: [ 'undefined', 'neutral', 'evil', 'good' ],
    };

   (...)

我可以在子无状态组件上接收 PropTypes,并使用它的值来验证其他道具,如下所示:

const SFComponent = ({
    anyProp,
    propsValues,
}) => {

    SFComponent.propTypes = {
        anyProp : PropTypes.oneOf( propsValues.anyProp ).isRequired,
        propsValues : PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string )),
    }; 

    (...)

但是当我尝试对子有状态组件做同样的事情时,它就不起作用了。我不能使用相同的 sintaxis 并且在验证类型时仍然没有收到道具。

class StatefulComponent extends React.Component {

    constructor( props ) {
        super( props );
        this.state = {
            anyAttribute : true,
            anotherAttribute : null,
        };
    }

    static propTypes = {
        anyProp : PropTypes.oneOf( this.props.propsValues.anyProp ).isRequired,
        propsValues : PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string )),

    (...)

上面的代码段抛出一个错误,指出是未定义的。我也尝试了其他可能性,但没有一个可行。

那么,关于如何实现与在无状态组件中实现的相同结果的任何想法,能够props.propsValues用作子有状态组件上所有道具的基本验证器?谢谢!

标签: reactjsreact-propsreact-proptypes

解决方案


this.props使用时不存在,propTypes因为propTypes是静态的。

SFComponent是一种无法按预期工作的 hack,因为SFComponent.propTypes只影响下一次渲染的组件。这应该使用 HOC 完成:

const withAnyProp = Comp => ({ anyProp, ...props }) =>
  const Wrapper = (...props) => <Comp {...props} />;
  Wrapper.propTypes = {
    anyProp : PropTypes.oneOf(anyProp).isRequired,
  };
  return <Wrapper {...props} />;
};
const SFComponentWithAnyProp = withAnyProp(SFComponent);

Orop 类型只是静态类型检查的内置替代品。最好使用 TypeScript 或 Flow 类型。

如果需要使用动态类型检查,可以在功能组件主体或类组件钩子方法中直接声明 props。


推荐阅读