React in WordPress
What is React?
Data => Rectangles
Why use React?
What's wrong with just outputting HTML?
It's about experience
Yeah but I love jQuery
or
Just use Vanilla
When to use React
- High Degree of interactivity
- Same Data appearing in multiple places
- When instant validation and feedback is helpful
When not to use React
- If you are just displaying static information
- If you only need to affect a few elements
Single Page Applications?
What about Vue?
or Angular?
or Mithril?
or Preact?
or Ember?
or Polymer?
or Knockout?
Let's take a look
function no_js_store() {
$products = array();
$query = new WP_Query( $query_args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$name = get_the_title();
$products[] = array(
"name" => $name,
);
}
}
foreach ($products as $product) {
$products_html .= return_product_html($product);
}
return $products_html;
}
add_shortcode( 'no-js-store', 'no_js_store' );
Let's take a look
function react_store() {
wp_enqueue_script( 'react-wp-demo-js' );
$products = array();
$query = new WP_Query( $query_args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$name = get_the_title();
$products[] = array(
"name" => $name,
);
}
}
$data_for_store_js = '{products:'.json_encode($products).'}';
$products_html .= '<script>var storeData = '.$data_for_store_js.';</script><section id="store-root"></section>';
return $products_html;
}
add_shortcode( 'react-store', 'react_store' );
Two Types of Components
Functional and Class
Functional (Stateless)
function Product(props) {
return (
<fieldset className={"product " +
(props.price <= props.moneyRemaining ? "affordable" : "unaffordable")
}>
<label className="product-label">
<h3 className="product-title">{props.name}</h3>
<p className="product-price">
<span className="product-price-symbol">$</span>
{props.price}
</p>
<p className="product-content">{props.content}</p>
<p className="product-category">{props.categories}</p>
</label>
<ProductCounter id={props.id} count={props.count}
setCount={props.setCount} minusCount={props.minusCount}
addCount={props.addCount} />
</fieldset>
);
}
function return_product_html($product) {
$output =
'<fieldset class="product">
<label class="product-label">
<h3 class="product-title">' . $product['name'] . '</h3>
<p class="product-price">
<span class="product-price-symbol">$</span>
' . $product['price'] . '
</p>
<p class="product-content">' . $product['content'] . '</p>
<p class="product-category">' . $product['categories'] . '</p>
</label>
<input class="product-count" type="number" value=0>
</fieldset>';
return $output;
}
Class Components
class Store extends React.Component {
constructor(props) {
super(props);
this.state = storeData;
}
addCount(product) {
let newState = this.state;
if (this.state.moneyRemaining >= newState.products[product].price) {
newState.products[product].count++;
}
this.setState({newState});
this.calculateRemaining();
}
render() {
return (
<div id="store-wrapper">
// Components here
</div>
);}}
But how do we affect the State from down the tree?
render() {
return (
<div id="store-wrapper">
<h3>You Have: ${this.state.moneyRemaining}</h3>
<form className="store" method="post">
{ this.state.products.map((product, i) => {
return (<Product key={i} id={i}
moneyRemaining={this.state.moneyRemaining}
name={product.name}
setCount={this.setCount.bind(this)} />);
})}
</form>
<h3>Estimated Bill:
${this.state.money - this.state.moneyRemaining}
</h3>
<button className="checkout">Check Out</button>
</div>
);
}
class ProductCounter extends React.Component {
constructor(props) {
super(props);
this.state = {count: this.props.count};
this.handleAdd = this.handleAdd.bind(this);
}
handleAdd(e) {
e.preventDefault();
this.props.addCount(this.props.id);
}
render() {
return (
<div className="product-counter">
<button className="product-count-button"
onClick={this.handleAdd}>+</button>
</div>
);
}
}
Build Steps?
Babel!
{
"name": "react-wp-demo",
"version": "0.0.1",
"description": "Demo of React in WordPress",
"main": "react-wp-demo.php",
"scripts": {
"babel": "babel",
"build": "babel js/src -d js",
"style": "sass --update styles"
},
"repository": {
"type": "git",
"url": "https://github.ncsu.edu/oitdesign/react-wp-demo.git"
},
"author": "Miles Elliott, OIT Design",
"devDependencies": {
"babel-cli": "^6.23.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.22.0",
"eslint": "^3.15.0",
"eslint-config-google": "^0.7.1",
"eslint-plugin-react": "^6.9.0"
}
}
{
"presets": [
"es2015",
"react"
]
}
What You Get
Nothing that was impossible
Support Concerns
-
Only supports IE9+
- You need to have a fallback if JavaScript is disabled
- Some Search Engines won't detect it (Google will now)
- The action is taking place on the client's device, so you are subject to potential bottlenecks there
Getting Started
Don't start with React in WordPress
Get down the React part first
facebook.github.io/react/docs/hello-world.html
Create React App
React in WordPress
By milesdelliott
React in WordPress
- 42