react - podsumowanie z placu boju

Post on 24-Jan-2017

128 Views

Category:

Internet

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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