Last active
January 1, 2021 07:24
-
-
Save KittyGiraudel/1f7a912b9548ec00c3a1 to your computer and use it in GitHub Desktop.
A simple textarea + counter component, fully commented for React beginners. :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import MyCoolTextarea from '../MyCoolTextarea'; | |
import MyCoolCounter from '../MyCoolCounter'; | |
const MyCoolComponent = React.createClass({ | |
// Define a method on the parent component describing what should happen when | |
// the textarea gets updated. At this point, the only thing needed is to store | |
// the length of the textarea’s content in a state on the parent component. | |
// | |
// In React, modifying a state will trigger a re-rendering of the component | |
// and all its children. This is precisely what you want as you need the span | |
// (MyCoolCounter) to be re-rendered with the new value. | |
// | |
// In this case `event.target` holds the textarea DOM node. You can access its | |
// value with `.value`, then its length with `.length`. | |
// | |
// Note, the `setState(..)` method also accepts a 2-arguments signature instead | |
// of an object, so you could do as well: | |
// `this.setState('length', event.target.value.length)` | |
handleChange (event) { | |
this.setState({ | |
length: event.target.value.length | |
}); | |
}, | |
// Here you render your parent component. It needs 2 children: the textarea | |
// (MyCoolTextarea) to which you pass the `handleChange` method as a prop so | |
// it can be called on change on the textarea. | |
// The counter itself (MyCoolCounter) only needs to know the length of the | |
// textarea’s content (stored in `this.state.length`), which is being passed | |
// as a prop again (`length`). | |
render () { | |
return ( | |
<div> | |
<MyCoolTextarea handleChange={this.handleChange} /> | |
<MyCoolCounter length={this.state.length} /> | |
</div> | |
); | |
} | |
}); | |
export default MyCoolComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
const MyCoolCounter = React.createClass({ | |
// The counter only needs the length of the textarea’s content to be correctly | |
// displayed. It is not necessarily required as we can assume the default | |
// value is 0. | |
// | |
// Note that the whole `propTypes` property could be omitted as it is only | |
// used for props validation. Basically it tells React to warn in case we pass | |
// a `length` prop that is not a number. | |
propTypes: { | |
length: React.PropTypes.number | |
}, | |
// Here we define a default value for the `length` prop in case it is not | |
// being passed for whatever reason. | |
getDefaultProps() { | |
return { | |
length: 0 | |
}; | |
}, | |
// When it comes to rendering the counter, it is basically a span displaying | |
// the `length` prop as part of a sentence. You could also make the plurali- | |
// sation a bit more clever here by having a conditional statement based on | |
// `this.props.length`. | |
render () { | |
return ( | |
<span>{this.props.length} character(s)</span> | |
); | |
} | |
}); | |
export default MyCoolCounter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
const MyCoolTextarea = React.createClass({ | |
// The textarea only needs one thing from the parent component: the method to | |
// be called on change (`onChange`). Therefore, it should be both required and | |
// a function. | |
// | |
// Note that the whole `propTypes` property could be omitted as it is only | |
// used for props validation. Basically it tells React to warn in case we pass | |
// a `handleChange` prop that is not a function, or if we do not pass a | |
// `handleChange` prop at all. | |
propTypes: { | |
handleChange: React.PropTypes.func.isRequired | |
}, | |
// The render method is extremely simple as it only consists on displaying a | |
// textarea to which is bound the `handleChange` method on the `onChange` | |
// event. | |
render () { | |
return ( | |
<textarea onChange={this.props.handleChange} /> | |
); | |
} | |
}); | |
export default MyCoolTextarea; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment