React
Introduction
- it is NOT a framework
- fast rendering library
Defining points:
- virtual DOM
- enforces component-driven development
Virtual DOM
- JavaScript is cheap
- touching the DOM is expensive
- as it involves rendering
- keeps an in-memory representation of the DOM
- when something changes, calculates a diff
- updates once
- only the parts that actually changed
Component Driven Dev.
Components are:
- the building block of a React application
- the only block of a React application
- hence the appeal of React
It allows you to split a complex problem in multiple simpler ones.
Component structure
import React from "react";
class Button extends React.Component {
render() {
return <div className="button"></div>;
}
}Minimal component
Highlights:
- all components extend React.Component
- HTML like syntax called JSX
- className attribute for CSS class
Component Properties
Properties are:
- an explicit way for a parent component to pass data to it's children
- a way for the children to notify parent about changes, through callbacks
class Button extends React.Component {
render() {
return (
<div className="button" onClick={this.props.onClick}>
{this.props.text}
</div>
);
}
}
Button.defaultProps = {
text: "Default Button Text",
onClick: () => {}
};Component State
- calling setState triggers a re-render
- setState calls are transparently bundled together
class CheckBox extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
checked: false
};
}
render() {
return (
<input type="checkbox"
checked={this.state.checked}
onClick={this.handleChange.bind(this)} />
);
}
}Component Lifecycle
Initialization:
- constructor
-
componentWillMount()
- once, before initial rendering
- setState will not trigger a re-render
- render()
-
componentDidMount()
- once, after initial rending
- DOM can be accessed
Component Lifecycle
State changes:
-
shouldComponentUpdate(nextProps, nextState)
- when new props or state are being received
-
componentWillUpdate(nextProps, nextState)
- no allowed setState here
- render()
-
componentDidUpdate(prevProps, prevState)
- DOM can be accessed
Component Lifecycle
Props changes:
-
componentWillReceiveProps(nextProps)
- when new props are received
- not on initial rendering
- shouldComponentUpdate(nextProps, nextState)
- render()
- componentDidUpdate(prevProps, prevState)
Component Lifecycle
Unmounting:
-
componentWillUnmount()
- immediately before unmount from the DOM
- perform cleanup operations here
Rendering children
this.props.children
- is an object when there is only one child
- is an array when there are multiple children
You can use the utility methods from React.Children:
- React.Children.map(children, child => {}, context)
- React.Children.forEach(children, child => {}, context)
- React.Children.toArray()
- React.Children.count()
Handling children:
- React.cloneElement(element, props, children);
- element.type
Rendering children
// simple approach
render() {
return <div>{this.props.children}</div>;
}
// adding or modifying child properties
render() {
return <div>{this.renderChildren()}</div>;
}
renderChildren() {
return React.Children.map(this.props.children, (child) => {
return React.cloneElement(child, {
key: child.props.id, // an id uniq to the child
overridenProp: "newVal",
newProp: "someVal"
});
});
}
// checking for a child type
renderChildren() {
return React.Children.map(this.props.children, (child) => {
// only render CheckButton 's
if (child.type == CheckButton) {
return child;
}
});
}Refs
Refs or references:
- gets the DOM node - for a DOM component
- gets the backing instance of a component - for a composite component
JSX
- doesn't return a component instance
- returns a representation of the component - a ReactElement
Refs break the encapsulation principle, try to avoid using them.
Refs
import ReactDOM from "react-dom";
class Container extends React.Component {
// accessing refs
componentDidMount() {
this.refs.title; // DOM node
this.tabView = $.tabView(this.refs.title);
this.refs.button; // React component instance
ReactDom.findDOMNode(this.refs.button); // DOM node
}
// attaching refs
render() {
return (
<div>
<span ref="title">Foo</span>
<MyComponent ref={(el) => {/**/}}
<Button ref="button"/>
</div>
);
}
componentWillUnmount() {
this.tabView.distroy();
}
}React
By kenjiru
React
An airplane overview of React
- 561