What is react?
- how does it differ from a framework?
Change Detection
Comparison of the big 3
AngularJS
React
Angular
Dirty Checking
const dirtyCheck = (lastState, newState) => deepEqualCheck(lastState, newState)
$digest.onDigest((components) => {
components
.filter(dirtyCheck)
.forEach((oldState, newState, component) => component.render(newState))
})
$digest.run() // runs over and over and over thousands of times in milliseconds
When Does it check?
- DOM Events
- Parent Component Changed
- Component props changed (html attributes)
Zone Change Detection
When Does it check?
- Zone changes (events)
const components = angularComponents() // List of angular components
components.forEach(component => {
component.onMarkedForChange((component) => {
component.root.children.forEach(component => component.update())
})
})
- Parents updated
Virtual Dom Diff
When Does it check?
- Component Changed (class props)
- Parent Component Changed
- Component props changed (html attributes)
whenShouldCheckForChange((oldComponent, newComponent) => {
const renderedOld = render(oldComponent),
renderedNew = render(newComponent)
if (isDifferent(renderedOld, renederedNew))
updateDom(newComponent.element, renderedOld)
})
How to create a react component
class MyComponent extends React.Component {
prop = 'World'
render() {
// Notice className instead of class
return <span className='test'>Hello {this.prop}<span>
}
}
ReactDOM.render(
<MyComponent/>,
document.getElementById('react-view-container')
)
JSX
- It's mostly HTML with a few differences
- Major difference is className because class is reserved
const ComponentTemplate = () => <div onClick={this.onClick}>
<img src={this.imageUrl}>
<span>{this.imageTitle}</span>
</div
const MajorComponent = () => (<div>
<ComponentTemplate/>
</div>)
Conditional Rendering
// Conditional Rendering Way 1
const HelloComponent = (props) => (<div>
{props.isMorning ? <GoodMorning/> : <Hello/>}
</div>)
// Or in a class
class HelloComponent extends React.Component {
render() {
const Greeting = this.pros.isMorning ? <GoodMorning/> : <Hello/>
return (<div>
<Greeting/>
{this.someProp && <GoodMorning/>}
</div>)
}
}
// Stop component from rendering
const GoodNightComponent = (props) => {
if (true)
return null // Will prevent rendering
return ...
}
Lists
class HelloComponent extends React.Component {
const data = [{id: 1}, {id: 2}, {id: 3}]
render() {
const greetings = R.map((a) => <span key={a.id}>a.id</span>, data)
return (<div>
{greetings}
</div>)
}
}
Lifecycle
Validating and Type Checking Component Props
class MyComponent extends React.Component {
static propTypes = {
myArray: React.PropTypes.array,
customArray: React.PropTypes.oneOf([1, 2, 3]),
customObject: React.Proptypes.shape({
name: React.PropTypes.string,
number: React.PropTypes.number
})
}
}
How Components Decide to Update
class MyComponent extends React.Component {
componentShouldUpdate() {
return true // defaults to this
}
}
class MyComponent extends React.PureComponent {
shouldComponentUpdate() {
return shallowPropDiffCheck(this) // not actual code
}
}
Ramda and React
const ComponentTrue = R.always(<TrueComponent/>)
const ComponentFalse = R.always(<FalseComponent/>)
const chooseComponent = R.ifElse(isTrue, ComponentTrue, ComponentFalse)
compose(chooseComponent, convertToBoolean)
Wrapping Up
- Don't Use Inheritance
- Be functional (pure functions are useful)
- Lift shared needs to parent components