mardi 21 juin 2016

When do React PropTypes get initialized?

I am having an issue with required PropTypes throwing errors. I would expect the PropType to throw an error if the Component was was being directly rendered. Here is a small sample of what I am trying to achieve.

You'll notice that the Button prop has a required PropType of handle click.

But I want the implementation of a Modal to be as simple as possible. And since I don't have the context of Modal I can not bind the handleClick method directly to the Button so I pass the Button in as child and map over the children adding the handleClick method to the child component. This works pretty well besides throwing the error for Button because <Button> gets called and checked before it truly gets rendered.

I have tried to do this a few other ways as well using Higher Order Components which worked as well. But the implementation seemed convoluted and tedious this seems like a much simpler way to just generate a Modal when it is needed. You don't need any props you just pass in a child component and it will add the click handler.

It would be awesome to either Bypass the proptypes check until it is actually rendered in Modal Component or maybe there is a simpler way, all feed back is welcomed.

https://jsfiddle.net/kriscoulson/00xLw0up/1/

var Button = (props) => {
	return <button onClick={props.handleClick}>{props.children}</button>
}

Button.propTypes = {
	handleClick: React.PropTypes.func.isRequired
}

class Modal extends React.Component {
	openModal () { 
  	console.log('Opening Modal.....')
  }
	childrenWithProps () {
		return React.Children.map(this.props.children,
			(child) => React.cloneElement(child, {
    		handleClick: this.openModal
      })
    );
  }
	render () {
  	return (
    	<div>
				{this.childrenWithProps()} 
      </div>
    );
  }
}

var App = () => 
	<Modal>
  	<Button>Launch Modal</Button>
	</Modal>

ReactDOM.render(
  <App/>,
  document.getElementById('container')
);
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

Aucun commentaire:

Enregistrer un commentaire