React: Required props provided with cloneElement still display a warning in the console

Created on 27 Jul 2015  ·  3Comments  ·  Source: facebook/react

I made an example so it's easier to understand, but basically a warning is displayed in the console because of "missing required props".

The props are given to the element with React.cloneElement so I wasn't expecting to get a warning of missing props. I understand this could be an edge case though...

https://jsfiddle.net/kdsvgbzu/1/

<A name="name" value="value">
    <B></B>
</A>
class A extends React.Component {
    render() {
        return (
            <div>
                {React.Children.map(this.props.children, function(child) {
                    return React.cloneElement(child, {
                        name: this.props.name,
                        value: this.props.value
                    });
                }, this)}
            </div>
        );
    }
}

A.propTypes = {
    name: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired
};

class B extends React.Component {
    render() {
        return <span>{this.props.name} : {this.props.value}</span>;
    }
}

B.propTypes = {
    name: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired
};

Most helpful comment

I don't know what was your real use-case @tleunen, but I stumbled upon this issue while implementing a reusable component that had the responsiblity to pass props to its children:

ReactDOM.render(
   <NumberSelector>
    <ComponentRequiringTheNumber />
  </NumberSelector>
)

In the end, I worked around the issue with what I found is a more elegant solution:

ReactDOM.render(
   <NumberSelector>
    {({number}) => <ComponentRequiringTheNumber number={number} />}
  </NumberSelector>
)

I like it much better since the dependency of ComponentRequiringTheNumber is explicit, and the role of NumberSelector becomes apparent. And this way, the props given to the nested component are only evaluated when it is relevant.

Applied to your Fiddle : https://jsfiddle.net/ap1e9rk3/1/

All 3 comments

This is intentional; validating props at element creation time produces more useful errors. It also more closely matches the behavior of static type systems like Flow. Best for now is to simply mark those props optional. We also may introduce a feature in the future called context that will give another supported way to pass props from a parent like A to a child like B.

That's what I thought. Thanks @spicyj

I don't know what was your real use-case @tleunen, but I stumbled upon this issue while implementing a reusable component that had the responsiblity to pass props to its children:

ReactDOM.render(
   <NumberSelector>
    <ComponentRequiringTheNumber />
  </NumberSelector>
)

In the end, I worked around the issue with what I found is a more elegant solution:

ReactDOM.render(
   <NumberSelector>
    {({number}) => <ComponentRequiringTheNumber number={number} />}
  </NumberSelector>
)

I like it much better since the dependency of ComponentRequiringTheNumber is explicit, and the role of NumberSelector becomes apparent. And this way, the props given to the nested component are only evaluated when it is relevant.

Applied to your Fiddle : https://jsfiddle.net/ap1e9rk3/1/

Was this page helpful?
0 / 5 - 0 ratings