Concepts
state VS. props
- State and Props are component data.
- A component can only change its own state, using
this.setState()
method, not its props. - If the state changes, the component and all children are automatically updated by React that runs the render() function.
Component example
A simple component with one property (title) and one state (counter). The button updates the counter state using setState
method.
var MyComponent = React.createClass({
getDefaultProps: function() {
return {
title: 'My defaut title'
};
},
getInitialState: function() {
return {
counter: 0
};
},
onClick: function () {
this.setState({
counter: this.state.counter + 1
});
},
render: function() {
return (
<div>
{ this.props.title }
{ this.state.counter }
<button onClick={ this.onClick }>INCREMENT</button>
</div>
);
}
});
Add a component to the HTML page
The following JavaScript code includes a component inside a DOM element, passing initial properties using the options variable.
var options = {
title: 'My component'
};
React.render(
React.createElement(MyComponent, options),
document.getElementById('app')
);
Nested components
Inside a component, sub-components can be used.
Any type of data can be passed to a component: arrays, objects, functions... don't forget the curly brackets { }
to pass data.
<MySubComponent items={ ['A', 'B'] } onSave={ saveFunction } />
JSX: tips and tricks
JSX syntax is a mix of JavaScript and HTML. The JSX online compiler can be used to find compilation issues.
Attributes
HTML attributes use JS syntax (camelCase).
For example: use className=... instead of class=...
<button className="btn btn-default">
IF
{ term == 'yearly' && (
<p>10%値引き<p>
) }
IF ELSE
{ term == 'monthly' ? (
<span>1ヶ月</span>
) : (
<span>12ヶ月</span>
)}
Compact version
<span>{ term == 'monthly' ? '1ヶ月' : '12ヶ月' }</span>
Loops
Loop through items of an array using the Array.map() function and a callback function
render: function() {
var menuItem = function(i) {
return(
<li>
<span>{'STEP' + i }</span>
</li>
);
};
return(
<ul>
{ [1, 2, 3].map(menuItem) }
</ul>
);
}
Inline style
Style property uses JSON syntax.
style={{ float: 'right', padding: 10 }}
Working with jQuery plugins.
Use the componentDidMount event to initialise jQuery plugins.
componentDidMount: function () {
var el = this.getDOMNode();
var $el = $(el);
var $form = $el.find('form');
$form.mySuperPlugin();
}
White spaces
White spaces are stripped. Use {' '}
to restore white spaces between tags like (between 2 buttons for example).
<button>Cancel</button>
{' '}
<button>OK</button>
Tag syntax /JSX errors
<body>
<br>
<MyApp>
</body>
=> Error "Expected corresponding XJS closing tag for MyApp"
Don't forget to close all tags! (components and html tags, xhtml syntax)
<body>
<br />
<MyApp />
</body>
=> OK!
Event handlers
1. Normal pattern
onDeleteAll: function (event) {
},
render: function() {
return (
<button onClick={ this.onDeleteAll }>Delete All</button>
);
}
2. How to pass extra data
In event handlers (onClick=...), use .bind(null, myData) to pass data to the event handler.
onEmailAction: function (email, actionCode, event) {
},
render: function() {
return (
<button
onClick={ this.onEmailAction.bind(null, email, 'MARK_AS_READ') }>
Mark as read
</button>
);
}
Mixins
Code can be shared between components using mixins.
var EmailFilterList = React.createClass({
mixins: [FilterListEventMixin],
render: function() {
...
Note about: in the JavsScript compiled file, mixins have to be loaded before the components that use the mixins.
Namespaced components
Sub-components can be attributes of a main component.
For example, a section used to create an accordion has 2 sub-components: title and body:
var MySection = React.createClass({...});
MySection.Title = React.createClass({...});
MySection.Body = React.createClass({...});
<MySection>
<MySection.Title>My title</MySection.Title>
<MySection.Body>
...
</MySection.Body>
</MySection>
Property validation
Use propTypes
to specify property types: array, function, string...
React.createClass({
propTypes: {
myOptionalArray: React.PropTypes.array
}
...
Add .isRequired
to make the property required.
myRequiredArray: React.PropTypes.array.isRequired
Available types:
- React.PropTypes.array
- React.PropTypes.bool
- React.PropTypes.func
- React.PropTypes.object
- React.PropTypes.number,
- React.PropTypes.string
- React.PropTypes.element (React component)
- React.PropTypes.instanceOf(MyClass) (an instance of a class)
- ...
Tools
Chrome React Extension => see the component tree!
Atom JSX Package
- JSX linter
- shortcuts
- HTML to JSX converter
Best practices
- Use state only in the top level and pass data to from parent to children using props.
- Keep business logic outside the component, using "model" (see TodoMCV example on Github)
- Document component properties using propTypes.