ReactPodsumowanie z placu boju
TOC1.React - TL;DR2.Część właściwa3.Krótko o
narzędziach
ReactTL;DR
<MeetJS when="03.10.2016"/>
<div> <h1>Meet.js</h1> <time>03.10.2016</time></div>
const MeetJS = props => ( <div> <h1>Meet.js</h1> <time>{props.when}</time> </div>);
class MeetJS extends React.Component { render() { return ( <div> <h1>Meet.js</h1> <time>{this.props.when}</time> </div> ); }}
const MeetJS = props => ( <div> <h1>Meet.js</h1> <time>{props.when}</time> <button onClick={() => this.setState({ started: true, })}> Lets start! </button> {this.state.started && <BeerBooth/>} </div>);
const MeetJS = props => ( <div> <h1>Meet.js</h1> <AtendeesList attendees={props.attendees}/> </div>);
Pytania?
Krótko o mnieW trzech memach
ReactPodsumowanie z placu boju
Komponenty są jak klasy
Properties === methods
<MeetJS when="03.10.2016"/>
new MeetJS() .setWhen('03.10.2016') .render();
Properties === API
<MeetJS ticketPrice={daysLeft => 0}/>
<div> <h1>Meet.js</h1> <BeerBooth onEmpty={() => this.panic() }/></div>
SRP głupcze!
Blob componentPo czym poznać?
Ilość kodu!
Za dużo właściwości
static propTypes = { id: PropTypes.string, label: PropTypes.string, changeHandler: PropTypes.func, checked: PropTypes.bool, wrapper: PropTypes.string, labelClass: PropTypes.string, type: PropTypes.string, setValue: PropTypes.func, getValue: PropTypes.func, resetValue: PropTypes.func, touched: PropTypes.bool, error: PropTypes.string, name: PropTypes.string, showError: PropTypes.func, onChange: PropTypes.func, preventHover: PropTypes.bool, onMouseOut: PropTypes.func,};
Za dużo stanów
this.state = { show: false, enableEdit: false, enableRemoveDropdown: false, enableDueDateDropdown: false, itemTitle: props.item.title, canCreate: true, canBeHidden: true, temporaryDueDate: undefined, temporaryAssigneeId: undefined, discardModalOpened: false, locked: false, wasUnchecked: false,};
… za dużo className
const todoListClass: string = cx({ 'todo-list-item__inline': true, 'todo-list-item__inline--hover': this.state.show, 'todo-list-item__inline--active': this.state.enableEdit, 'todo-list-item__inline--loading': this.state.locked || item.notSaved, 'todo-list-item__inline--hidden': this.props.item.hidden, 'todo-list-item__inline--edit': this.isDrawerOpened(), 'todo-list-item__inline--updated': item.state.updated, 'todo-list-item__inline--updated-comment': item.state.firstUnreadCommentId,});
const dragClass: string = cx({ 'todo-list-item__drag': true, 'todo-list-item__drag--hover': this.state.show && !this.state.enableEdit,});
const editControlsClass: string = cx({ 'todo-list-item__edit__controls': true, 'todo-list-item__edit__controls--active': this.state.show,});
const editClass: string = cx({ 'todo-list-item__edit': true, 'todo-list-item__edit--hover': this.state.show, 'todo-list-item__edit--active': this.state.enableEdit,});
const editTodoButtonClass: string = cx({ 'todo-list-item__edit__toggle': true, 'todo-list-item__edit__toggle--hide': this.state.enableEdit,});
const saveTodoButtonClass: string = cx({ 'todo-list-item__add': true, 'todo-list-item__add--active': this.state.enableEdit, 'todo-list-item__add--disabled': !this.state.canCreate,});
const discardButtonClass: string = cx({ 'todo-list-item__discard': true, 'todo-list-item__discard--show': this.state.enableEdit,});
const todoItemInfoClass: string = cx({ 'todo-list-item__info': true, 'todo-list-item__info--hide': this.state.enableEdit,});
const editTodoInputClass: string = cx({ 'todo-list-item__edit__input': true, 'todo-list-item__edit__input--active': this.state.enableEdit,});
const todoItemEditDescriptionClass: string = cx({ 'todo-list-item__edit__description': true, 'todo-list-item__edit__description--show': this.state.enableEdit,});
const removeTodoClass: string = cx({ 'todo-list-item__remove': true, 'todo-list-item__remove--edit': this.state.enableEdit,});
const toggleDropdownClass: string = cx({ 'todo-list-item__remove__dropdown': true, 'todo-list-item__remove__dropdown--show': this.state.enableRemoveDropdown,});
Jedyne rozwiązanie
Komunikacja między komponentami
Top to bottomParent > child
const MeetJS = props => ( <div> <BeerBooth opened={props.when > new Date()} /> <Attendees list={props.attendess} /> </div>);
FTW!
Context
class BeerBooth extends React.Component { static contextTypes = { opened: React.PropTypes.bool, };
render() { return ( <div> <h1>Beer!</h1> <h2>{this.context.opened ? 'Opened!' : 'Closed'}</h2> </div> ); }}
class MeetJS extends React.Component { static childContextTypes = { opened: React.PropTypes.bool, };
getChildContext() { return { opened: this.props.when > new Date(), }; }
render() { return ( <div>{/* ... */}</div> ); }}
Referencje
class MeetJS extends React.Component { componentDidMount() { if (this.props.when > new Date()) { this.beer.open(); // this.beer.setState({opened: true}); } }
render() { return ( <div> <BeerBooth ref={el => { this.beer = el; }}/> </div> ); }}
Bottom to topChild > parent
Właściwości jako eventy
const MeetJS = props => ( <div> <h1>Meet.js</h1> <BeerBooth onEmpty={() => this.setState({ closed: true, })}/> </div>);
Referencje
const MeetJS = props => ( <div> <h1>Meet.js</h1> <BeerBooth partyHost={this}/> </div>);
STAHP
Context
class MeetJS extends React.Component { static childContextTypes = { endParty: React.PropTypes.func, };
getChildContext() { return { endParty: () => this.setState({ closed: true, }), }; }
render() { return ( <div>{/* ... */}</div> ); }}
Komunikacja dwustronnaTaki pomysł
Context + event emitter
FLUX głupcze!
Unidirectional data flow
High Order Components
… komplikują korzystanie z referencji
… uniemożliwiają korzystanie z shallow
render
Trochę o testowaniu
Shallow renderof <MeetJS/>
<div> <h1>Meet.js</h1> <BeerBooth/></div>
Full renderof <MeetJS/>
<div> <h1>Meet.js</h1> <div class="beer-booth"> <div id="theGuy">•|龴 龴◡ |•</div> <ul class="beer-booth--kegs-list"> <li>Beer keg #1</li> <li>Beer keg #2</li> <li>Beer keg #3</li> </ul> </div></div>
Testy jednostkowe to nie testy integracyjne
Shallow render != full render
Unit test powinien korzystać z shallow
render
Full render zostawmy dla testów e2e
Unit testy powinny być szybkie
Szanuj swój czas :)
Rozdziel testyUnit test / e2e
Natywne narzędzia mogą nie wystarczać
Szybko o narzędziach
Hot Module ReloadFTW
Eslint… skąd u niego taka spina?
Mocha > Karma
Pytania?
fb:twt:gh:
radoslaw.mejer_radmenradmen
Dzięki!
Top Related