Skip to content

Instantly share code, notes, and snippets.

@KittyGiraudel
Last active January 1, 2021 07:24
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KittyGiraudel/1f7a912b9548ec00c3a1 to your computer and use it in GitHub Desktop.
Save KittyGiraudel/1f7a912b9548ec00c3a1 to your computer and use it in GitHub Desktop.
A simple textarea + counter component, fully commented for React beginners. :)
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;
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;
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