To make more composable React components, you can define common APIs for similar component types.
[00:00] When creating React components one key tenet should be that your components should be reusable as well as composable. Now here in our code view we've got the slider component that we created in the refs video, so hopefully you guys saw that, but basically we've got these slider components that we can drag around and they update their value. What I'm going to do is strip these down, or strip this down to just one slider component. So I'll go ahead and get rid of the rest of these guys.
[00:33] When we save that, we can see it's not such a great component, we don't even necessarily need a component for this guy, but what we're going to do is we're going to rename this to numinput, we're going to create a more composable, more reusable component, taking advantage of the similar APIs between the number input and the range input. So to get us started I'm going to create some prop types, so we've got numinput.proptypes, set that to an object and for the sake of brevity I'm just going to paste these in, we'll take a quick look at them.
[01:10] We've got min set to a number, max set to a number, step and value set to a number. We've got a property of label set to a string, and that's going to allow us to take this label right here out of the control of the user and put it into the control of the component. We've got our update method which is our only required method and that has a type of function, and then finally we've got a type property which is type of oneof, which takes in an array, and we are willing to accept number or range as a string.
[01:46] Now we're going to go and set up our numinput default props, and again I'm just going to paste these in for the sake of brevity. We've got min and max both set to a default of 0step set to 1, val set to 0label set to an empty string, and for a default we're going to use range. Now here in our component, going to paste in some initial settings. So our type, min, max, step, and default value are all set to the props that are passed into our component, our update method does not change, we need to implement our label which we'll drop right here after the input.
[02:36] We may want to come back and make an option to have that be before or after the input. So to implement that I'm just going to say let label = thisprops.label <> '' and if that's the case, we'll go ahead and output a label tag, we won't worry about the for value, and it's innerHTML will be this.props.label, and just for this demo, we'll go ahead and also output this.props.val otherwise it will just be an empty string. We'll go and save that.
[03:21] So up here where we're utilizing that, we won't need this label right here, go ahead and break this out a bit so we can see. Set our min = 0our max = 255, our step = 1, our value = this.state.red and we're going to need to coerce that into a number since the component is expecting a number. We'll set our label to red. So let's go ahead and save that and try it out. We've got our slider, and we've got our label, and we've got our value.
[04:04] If we wanted to come over here and update our type to be a type of number input, now we've got our number input and everything seems to be working just fine. If we want to mess around and say this our step of 001 we can do that. That will step by .01. If we want to switch that back to the default of range, now you can see it is in fact stepping by that decimal value. So now we have a component that's much more reusable and much more composable.
There's no clear method in React for extending an existing component, but mixins are a great place to start.
You could also wrap the component you want to inherit from and call it's methods using a ref.
<code> var App = react.createClass({ method: function(){ return this.refs.comp.method(); }, render: function(){ return <InheritFromThisComponent ref="comp" /> } }) </code>In your example, the input is an uncontrolled component because you use defaultvalue, instead of a value, is that correct? Does the code need to be changed if I make it a controlled component instead?
Inhale and exhale, you are teaching man!
I am using React version 0.14.0 on a Mac OSX
When I type this code in, it is functional and I am getting an error of "Uncaught TypeError: React.findDOMNode is not a function"
I understand React.findDOMNode is introduced in the 0.13.0 release of React. Why is this error being thrown? Did it get deprecated in 0.14.0?
Thanks
In React v0.14 some methods like findDOMNode have been moved to a separate package.
Include https://fb.me/react-dom-0.14.0.js in your application and use ReactDOM.findDOMNode, ReactDOM.render, and ReactDOM. unmountComponentAtNode where applicable.
Hi Joe,In the beginning of this lecture you have mentioned that you have created all the input range components using refs in a separate lecture,I am unable to find the lecture in this series.If possible can you please provide me a link to that lecture.
Thanks
Same here. And there is nothing in the course repo either. Thanks!
Hi Mitesh, even though I didn't find the original code for the various inputs, I did manage to get the code that we start with here to work. When I push it to github, I will share the link here. Perhaps this will help?
Mitesh (and anyone else who is interested), here is the link of the commit containing the original code re various inputs/input refs: https://github.com/interglobalmedia/react-basics/commit/ab93964c44e393cc11e98584915ac79b6e39f85f Hope this helps!
Hey - What would you suggest that if we wanted to reuse "NumInput" but "add" some additional props or whatever, is there a way to "extend" it. Because we might want to use NumInput , but might need something additional so its usage isn't so particular.