Last active
November 17, 2016 12:02
-
-
Save guptag/4947ec5056f443603e1c to your computer and use it in GitHub Desktop.
ReactJS
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
// React Class template with inlined documentation from | |
// http://facebook.github.io/react/docs/component-specs.html | |
var component = React.createClass({ | |
/***** Core Methods *****/ | |
render: function () { | |
// Returns ReactComponent | |
// When called, it should examine this.props and this.state and return a single child component. | |
// This child component can be either a virtual representation of a native DOM component | |
// (such as <div /> or React.DOM.div()) or another composite component that you've defined yourself. | |
// The render() function should be pure, meaning that it does not modify component state, | |
// it returns the same result each time it's invoked, and it does not read from or write | |
// to the DOM or otherwise interact with the browser (e.g., by using setTimeout). | |
// If you need to interact with the browser, perform your work in componentDidMount() or the other lifecycle methods instead. | |
// Keeping render() pure makes server rendering more practical and makes components easier to think about. | |
/* | |
// transferPropsTo() will take any props passed to CheckLink | |
// and copy them to <a> | |
return this.transferPropsTo(<a>{'√ '}{this.props.children}</a>); | |
*/ | |
/* | |
return ( | |
<div> | |
<SearchBar | |
filterText={this.state.filterText} | |
inStockOnly={this.state.inStockOnly} | |
onUserInput={this.handleUserInput} | |
/> | |
<ProductTable | |
products={this.props.products} | |
filterText={this.state.filterText} | |
inStockOnly={this.state.inStockOnly} | |
/> | |
</div> | |
); | |
*/ | |
}, | |
getInitialState: function () { | |
// Returns Object | |
// Invoked once before the component is mounted. The return value will be used as the initial value of this.state. | |
}, | |
getDefaultProps: function () { | |
// Returns Object | |
// Invoked once when the component is mounted. Values in the mapping will be set on this.props if that prop is not specified by the parent component (i.e. using an in check). | |
// This method is invoked before getInitialState and therefore cannot rely on this.state or use this.setState. | |
}, | |
propTypes: { | |
// http://facebook.github.io/react/docs/reusable-components.html | |
}, | |
mixins: [ ], // http://facebook.github.io/react/docs/reusable-components.html | |
statics: { | |
// The statics object allows you to define static methods that can be called on the component class. For example: | |
/* | |
var MyComponent = React.createClass({ | |
statics: { | |
customMethod: function(foo) { | |
return foo === 'bar'; | |
} | |
}, | |
render: function() { | |
} | |
}); | |
MyComponent.customMethod('bar'); // true | |
*/ | |
}, | |
/***** Lifecycle Methods *****/ | |
componentWillMount: function () { | |
// Invoked once, immediately before the initial rendering occurs. | |
// If you call setState within this method, render() will see the updated state | |
// and will be executed only once despite the state change. | |
}, | |
componentDidMount: function () { | |
// Invoked immediately after rendering occurs. | |
// At this point in the lifecycle, the component has a DOM representation | |
// which you can access via this.getDOMNode(). | |
// If you want to integrate with other JavaScript frameworks, set timers using | |
// setTimeout or setInterval, or send AJAX requests, perform those operations in this method. | |
}, | |
componentWillReceiveProps: function(nextProps) { | |
// Invoked when a component is receiving new props. | |
// This method is not called for the initial render. | |
// Use this as an opportunity to react to a prop transition before render() is called | |
// by updating the state using this.setState(). The old props can be accessed via this.props. | |
// Calling this.setState() within this function will not trigger an additional render. | |
/*this.setState({ | |
likesIncreasing: nextProps.likeCount > this.props.likeCount | |
}); */ | |
}, | |
shouldComponentUpdate: function(nextProps, nextStat) { | |
// Invoked before rendering when new props or state are being received. | |
// This method is not called for the initial render or when forceUpdate is used. | |
// Use this as an opportunity to return false when you're certain that the transition to | |
// the new props and state will not require a component update. | |
/* | |
return !equal(nextProps, this.props) || !equal(nextState, this.state); | |
*/ | |
// If shouldComponentUpdate returns false, then render() will be completely | |
// skipped until the next state change. | |
// (In addition, componentWillUpdate and componentDidUpdate will not be called.) | |
}, | |
componentWillUpdate: function (nextProps, nextState) { | |
// Invoked immediately before rendering when new props or state are being received. | |
// This method is not called for the initial render. | |
// Use this as an opportunity to perform preparation before an update occurs. | |
// You cannot use this.setState() in this method. | |
// If you need to update state in response to a prop change, | |
// use componentWillReceiveProps instead. | |
}, | |
componentDidUpdate: function (prevProps, prevState) { | |
// Invoked immediately after updating occurs. This method is not called for the initial render. | |
// Use this as an opportunity to operate on the DOM when the component has been updated. | |
}, | |
componentWillUnmount: function () { | |
// Invoked immediately before a component is unmounted from the DOM. | |
// Perform any necessary cleanup in this method, such as invalidating timers or cleaning | |
// up any DOM elements that were created in componentDidMount. | |
} | |
}); |
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
// All examples in one place | |
// from: http://facebook.github.io/react/docs/getting-started.html | |
/** @jsx React.DOM */ | |
var ProductCategoryRow = React.createClass({ | |
render: function() { | |
return (<tr><th colSpan="2">{this.props.category}</th></tr>); | |
} | |
}); | |
var ProductRow = React.createClass({ | |
render: function() { | |
var name = this.props.product.stocked ? | |
this.props.product.name : | |
<span style={{color: 'red'}}> | |
{this.props.product.name} | |
</span>; | |
return ( | |
<tr> | |
<td>{name}</td> | |
<td>{this.props.product.price}</td> | |
</tr> | |
); | |
} | |
}); | |
var ProductTable = React.createClass({ | |
render: function() { | |
console.log(this.props); | |
var rows = []; | |
var lastCategory = null; | |
this.props.products.forEach(function(product) { | |
if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) { | |
return; | |
} | |
if (product.category !== lastCategory) { | |
rows.push(<ProductCategoryRow category={product.category} key={product.category} />); | |
} | |
rows.push(<ProductRow product={product} key={product.name} />); | |
lastCategory = product.category; | |
}.bind(this)); | |
return ( | |
<table> | |
<thead> | |
<tr> | |
<th>Name</th> | |
<th>Price</th> | |
</tr> | |
</thead> | |
<tbody>{rows}</tbody> | |
</table> | |
); | |
} | |
}); | |
var SearchBar = React.createClass({ | |
handleChange: function() { | |
this.props.onUserInput( | |
this.refs.filterTextInput.getDOMNode().value, | |
this.refs.inStockOnlyInput.getDOMNode().checked | |
); | |
}, | |
render: function() { | |
return ( | |
<form onSubmit={this.handleSubmit}> | |
<input | |
type="text" | |
placeholder="Search..." | |
value={this.props.filterText} | |
ref="filterTextInput" | |
onChange={this.handleChange} | |
/> | |
<p> | |
<input | |
type="checkbox" | |
value={this.props.inStockOnly} | |
ref="inStockOnlyInput" | |
onChange={this.handleChange} | |
/> | |
Only show products in stock | |
</p> | |
</form> | |
); | |
} | |
}); | |
var FilterableProductTable = React.createClass({ | |
getInitialState: function() { | |
return { | |
filterText: '', | |
inStockOnly: false | |
}; | |
}, | |
handleUserInput: function(filterText, inStockOnly) { | |
this.setState({ | |
filterText: filterText, | |
inStockOnly: inStockOnly | |
}); | |
}, | |
render: function() { | |
return ( | |
<div> | |
<SearchBar | |
filterText={this.state.filterText} | |
inStockOnly={this.state.inStockOnly} | |
onUserInput={this.handleUserInput} | |
/> | |
<ProductTable | |
products={this.props.products} | |
filterText={this.state.filterText} | |
inStockOnly={this.state.inStockOnly} | |
/> | |
</div> | |
); | |
} | |
}); | |
var PRODUCTS = [ | |
{category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'}, | |
{category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, | |
{category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, | |
{category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, | |
{category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, | |
{category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} | |
]; | |
React.renderComponent(<FilterableProductTable products={PRODUCTS} />, document.body); | |
/*************************************************************************************/ | |
// Window.Resize (global dom event handlers) | |
/** @jsx React.DOM */ | |
var Box = React.createClass({ | |
getInitialState: function() { | |
return {windowWidth: window.innerWidth}; | |
}, | |
handleResize: function(e) { | |
this.setState({windowWidth: window.innerWidth}); | |
}, | |
componentDidMount: function() { | |
window.addEventListener('resize', this.handleResize); | |
}, | |
componentWillUnmount: function() { | |
window.removeEventListener('resize', this.handleResize); | |
}, | |
render: function() { | |
return <div>Current window width: {this.state.windowWidth}</div>; | |
} | |
}); | |
React.renderComponent(<Box />, mountNode); | |
/*************************************************************************************/ | |
// Get initial data from AJAX | |
/** @jsx React.DOM */ | |
var UserGist = React.createClass({ | |
getInitialState: function() { | |
return { | |
username: '', | |
lastGistUrl: '' | |
}; | |
}, | |
componentDidMount: function() { | |
$.get(this.props.source, function(result) { | |
var lastGist = result[0]; | |
this.setState({ | |
username: lastGist.user.login, | |
lastGistUrl: lastGist.html_url | |
}); | |
}.bind(this)); | |
}, | |
render: function() { | |
return ( | |
<div> | |
{this.state.username}'s last gist is | |
<a href={this.state.lastGistUrl}>here</a>. | |
</div> | |
); | |
} | |
}); | |
React.renderComponent( | |
<UserGist source='https://api.github.com/users/octocat/gists' />, | |
mountNode | |
); | |
/*************************************************************************************/ | |
// If else JSX | |
/** @jsx React.DOM */ | |
React.renderComponent(<div id={condition ? 'msg' : ''}>Hello World!</div>, mountNode); | |
/*************************************************************************************/ | |
// Add Remove CSS classes | |
render: function() { | |
var cx = React.addons.classSet; | |
var classes = cx({ | |
'message': true, | |
'message-important': this.props.isImportant, | |
'message-read': this.props.isRead | |
}); | |
// same final string, but much cleaner | |
return <div className={classes}>Great, will be there.</div>; | |
} | |
/*************************************************************************************/ | |
// MixIns | |
// They fire in the order they're specified in the mixins array | |
// Take a look at http://jsfiddle.net/zpao/9CDku/ as an example. | |
// The method defined in the component itself is called last, after all the mixin methods. | |
// http://jsfiddle.net/9CDku/1/ | |
// I extended Paul's example to show the un-mounting order as well: | |
// http://jsfiddle.net/kinergy/3Ln3v/ | |
/** @jsx React.DOM */ | |
var SetIntervalMixin = { | |
componentWillMount: function() { | |
this.intervals = []; | |
}, | |
setInterval: function() { | |
this.intervals.push(setInterval.apply(null, arguments)); | |
}, | |
componentWillUnmount: function() { | |
this.intervals.map(clearInterval); | |
} | |
}; | |
var TickTock = React.createClass({ | |
mixins: [SetIntervalMixin], // Use the mixin | |
getInitialState: function() { | |
return {seconds: 0}; | |
}, | |
componentDidMount: function() { | |
this.setInterval(this.tick, 1000); // Call a method on the mixin | |
}, | |
tick: function() { | |
this.setState({seconds: this.state.seconds + 1}); | |
}, | |
render: function() { | |
return ( | |
<p> | |
React has been running for {this.state.seconds} seconds. | |
</p> | |
); | |
} | |
}); | |
React.renderComponent( | |
<TickTock />, | |
document.getElementById('example') | |
); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment