jzkarap
jzkarap

Reputation: 31

How to enfore prop types on connected component?

Been banging my head against the wall on this one. I have a component I use for language translations, that is connected to my redux store, where language values are kept. It gets provided a language key and renders blurred placeholder text until the language values are put into state, in which case it renders the requested strings. I am trying to enforce this as the only prop type for props of several components. But I keep seeing errors.

import React from "react";
import PropTypes from 'prop-types';
import { connect } from "react-redux";
import { dummyText } from "../../constants/placeholderDummyText";
import { substrByWordCount } from "../../utilities/strings";

// displays blurred dummy text if placeholder is supplied, else displays the language value for the key provided
export const TextValue = ({ language, langKey, placeholderWordCount = 1 }) => {

    const hasLanguageAvailable = Object.entries(language).length !== 0;

    const placeholder = substrByWordCount(dummyText, placeholderWordCount);

    return hasLanguageAvailable ? (
        <span dangerouslySetInnerHTML={{
            __html: language[langKey]
        }} />
    ) : (
            <span className='blurredText'>
                {placeholder}
            </span>
        );
};

TextValue.propTypes = {
    /**
     * The key of the language value to retrieve
     */
    langKey: PropTypes.string.isRequired,
    /**
     * How many blurred words to surface as placeholder elements while waiting for language to flow in
     */
    placeholderWordCount: PropTypes.number
}


function mapStateToProps(state) {
    return {
        language: state.language.values
    };
};

export default connect(mapStateToProps)(TextValue);

This is my TextValue component. I am trying to use it as a prop type in some components as follows:

TextInput.propTypes = {
    /**
     * The name of the form input.
     */
    name: PropTypes.string.isRequired,
    /**
     * The placeholder text to display within the input field. Gets its value from the input name if not supplied.
     */
    placeholder: PropTypes.string,
    /**
     * The input's label.
     */
    label: PropTypes.instanceOf(TextValue).isRequired,
    /**
     * Represents whether or not the input is required in order to submit the form to which it belongs
     */
    required: PropTypes.bool
}

This results in an error from React:

Warning: Failed prop type: Invalid prop 'title' of type 'Object' supplied to 'TextInput', expected instance of 'TextValue'.

Is it possible to check the type of my TextValue export? Since it is a functional component, does it require a different method of enforcing it as a prop type?

Upvotes: 1

Views: 707

Answers (1)

lavor
lavor

Reputation: 1877

Try PropTypes.element (for a React element, i.e. <MyComponent />) or PropTypes.elementType (for a React element type, i.e. MyComponent) instead of PropTypes.instanceOf:

// ...
    label: PropTypes.elementType.isRequired,
// ...

PropTypes.instanceOf is used for an instance of a JS class not for a React component.

See this answer.

Upvotes: 1

Related Questions