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