Notes from a beginner's perspective on things that may trip you up when you start using React, the JS interface library
To work properly and allow user modification, form element components like <input>
s must:
- set the value attribute of the element using the component state, e.g.
value={this.state.value}
- rely on an
onChange
handler to keep the component state in sync with the element value e.g.
<input type="text" onChange={function(event) { this.state.value = event.target.value }} />
- define
getInitialState
to initialize the component by settingthis.state.value
to the desired value on page-load
In JSX, HTML attributes use camelCase even though it looks like HTML, so, e.g.
<input type="text" readOnly />
<td rowSpan="4" />
When mixing text and inline elements, only spaces inside an element or a continuous block of text are preserved. This is different from HTML, where linebreaks and indendation are treated as whitespace always. For example:
<p>
This is a paragraph
<strong>with some bold text</strong>
and some <em>italic text</em>.
</p>
This code renders as:
This is a paragraphwith some bold textand some italic text.
Either keep inline tags on the same line as other text, or ensure spaces are inside inline elements:
<p>
This is a paragraph
<strong> with some bold text</strong>
<span> and some </span>
<em>italic text</em>.
</p>
Each item rendered in a list (e.g. using anArray.map()
) should include a unique key, or React will tell you you're a bad person, e.g.
render({this.props.results.map(function(result, index) {
return <div key={'item' + index}>{result}</div>;
})})
When considering using shouldComponentUpdate
to control rendering updates, note that returning false
prevents all updates from children of the component from re-rendering as well, so it's only safe to do if you can be sure nothing nested inside your component has changed.
A parent component can set a callback property on a child component that the child can then call when something has changed the parent needs to know about. Useful pattern for form components that want to, e.g. validate child component field values.
var MyForm = React.createClass({
getInitialState: function() {
return { value: 'foo' };
},
onInputChange(newValue) {
this.setState({ value: newValue });
// insert validation call here
},
render: function() {
return (
<form>
<MyComplicatedField onChange={this.onInputChange} value={this.state.value} />
</form>
);
}
});
var MyComplicatedField = React.createClass({
onInputChange: function(event) {
this.props.onChange(event.target.value);
},
render: function() {
return (
<input type="text" onChange={this.onInputChange} value={this.props.value} />
);
}
});