wyboista ścieżka mocy - case study o2.pl
Radosław Rosłaniec
React
alt.js
ES2015 + Babel + Webpack
=
Grid Container
Tabs
Tab
Boxes Container
Box
Title
componentWillMount i (jego) księga tajemnic
//stuff
componentWillMount() {
window.addEventListener('focus', this.handleWindowFocus)
}
//stuff
//SSR friendly stuff
componentDidMount() {
window.addEventListener('focus', this.handleWindowFocus)
}
//SSR friendly stuff
Okej. Zamontowałeś? Odmontuj!
//stuff
componentDidMount() {
window.addEventListener('focus', this.handleWindowFocus)
this.intervalId = setInterval(() => {
console.log('tick')
}, 1000)
}
componentWillUnmount() {
window.removeEventListener('focus', this.handleWindowFocus)
clearInterval(this.intervalId)
}
//stuff
Binding context
class App extends React.Component {
handleUpdate(event) {
console.log('update handler')
}
render() {
return (
<input onChange={this.handleUpdate.bind(this)} />
)
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.handleUpdate = this.handleUpdate.bind(this)
}
handleUpdate(event) {
console.log('update handler')
}
render() {
return (
<input onChange={this.handleUpdate} />
)
}
}
Domyślne wartości
class Title extends React.Component {
render() {
return (
<div>
{this.props.title || ''}
</div>
)
}
}
Title.displayName = 'Title'
export default Title
const emptyTitle = ''
class Title extends React.Component {
render() {
return (
<div>
{this.props.title || emptyTitle}
</div>
)
}
}
Title.displayName = 'Title'
export default Title
class Title extends React.Component {
render() {
return (
<div>
{this.props.title}
</div>
)
}
}
Title.displayName = 'Title'
Title.defaultProps = {
title: ''
}
export default Title
propTypes
class Article extends React.Component {
render() {
const video = this.props.video
return (
<div>
{this.props.title}
<div>
{video ? <div>
<span>{video.title}</span>
<video>
<source src={video.url} type="video/mp4">
</video>
</div> : null}
</div>
</div>
)
}
}
Article.displayName = 'Article'
Article.defaultProps = {
title: ''
}
Article.propTypes = {
title: React.PropTypes.string,
video: React.PropTypes.shape({
url: React.PropTypes.string,
title: React.PropTypes.string
})
}
export default Article
eslint airbnb
mixins
mixins
komponent wyższego poziomu
your_project
|--actions/
| |--MyActions.js
|--sources/
| |--MyStoreSource.js
|--stores/
| |--MyStore.js
|--components/
| |--MyComponent.jsx
|--alt.js
|--app.js
Show me the code!
//actions/my-store.js
import { alt } from '../alt.js'
class Actions {
constructor() {
this.generateActions('fetchItems', 'setItems', 'fetchFailed')
}
}
export let MyStoreActions = alt.createActions(Actions)
//stores/my-store.js
import { alt } from '../alt.js'
import { MyStoreActions } from '../actions/my-store.js'
import { MyStoreSource } from '../sources/my-store.js'
class Store {
constructor() {
this.bindActions(MyStoreActions)
this.registerAsync(MyStoreSource)
this.state = {
items: []
}
}
onFetchItems() {
this.getInstance().fetchItems()
}
onSetItems(items){
this.setState({ items })
}
onFetchFailed() {
//handle error
}
}
export const MyStore = alt.createStore(Store, 'MyStore')
//sources/my-store.js
import { MyStoreActions } from '../actions/my-store.js'
export const MyStoreSource = {
fetchItems: {
remote() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([1,2,3]);
}, 1000)
})
},
success: MyStoreActions.setItems,
error: MyStoreActions.fetchFailed
}
}
//components/my-component.js
import React from 'react'
import AltContainer from 'alt-container'
import { MyStore } from '../stores/my-store.js'
import { MyStoreActions } from '../actions/my-store.js'
import { Items } from './items.js'
class ItemsContainer extends React.Component {
componentWillMount() {
MyStoreActions.fetchItems()
}
render() {
return (
<AltContainer store={MyStore} actions={MyStoreActions}>
<Items />
</AltContainer>
)
}
}
ItemsContainer.displayName = 'ItemsContainer'
export default ItemsContainer
//components/items.js
import React from 'react'
class Items extends React.Component {
render() {
return (
<div>
{this.props.MyStore.items.map(item => <div>{item}</div>)}
</div>
)
}
}
Items.displayName = 'Items'
export default Items
Silne strony alt.js
- prostota
- zarządzanie stanami
- AltContainer