Simen Brekken (@simenbrekken)
Daniel Mahal (@danielmahal)
github.com/unfoldoslo
Design byrå
Sterkt tekniskt fokus
Praktisk tilnærming, prototyping og eksperimentering
Produkt
Farge
Størrelse
Pris
Prismodell
{
"id": 7,
"status": "fulfilled",
"items": [{
"status": "fulfilled",
"shippedQuantity": 1,
"returnedQuantity": 0,
"id": 11,
"productName": "Alpine Jacket",
"brandName": "PUMA",
"variantName": "Blue",
"size": "S",
"ean": 217445280878,
"quantity": 1,
"price": 299.0,
"vat": 59.8,
"total": 299.0,
"variant": {
"id": 1108,
"ean": 217445280878,
"name": "Blue",
"images": [{
"id": "products/u5k4pz8mhkns2drq6hcz",
"height": 1710,
"width": 1080
}],
"price": {
"retail": 2999.0,
"normal": 2999.0,
"discounted": 300.0,
"campaign": null,
"current": {
"type": 2,
"price": 300.0,
"vat": 60.0
},
"vat": 25.0
},
"size": "S",
"extArticleId": null,
"stock": {
"available": 0,
"threshold": 0
}
},
"product": {
"id": 1051,
"name": "Alpine Jacket",
"description": "Intern link: [Merker](/merker)\n\nEkstern link: [Google](http://google.com)",
"shortDescription": "Denne nye modellen fra Bjørn Dæhlie er laget i et 2-lags elastisk softshellmateriale",
"brand": {
"id": 1010,
"name": "PUMA",
"logo": {
"id": "0",
"width": null,
"height": null
}
},
"tags": ["AntonSportWebShopAPI.Models.Tag", "AntonSportWebShopAPI.Models.Tag", "AntonSportWebShopAPI.Models.Tag"],
"packageSize": "Normal",
"currentPrice": 190.0,
"version": "AAAAAAAACyo=",
"createdAt": "2014-11-05T15:34:44.717+00:00",
"modifiedAt": "2014-11-24T20:44:01.533+00:00",
"createdBy": "0",
"modifiedBy": "0"
}
}],
"customer": {
"name": "S",
"email": "simen@unfold.no",
"mobile": null
},
"shipping": {
"address": {
"street": "Pilestredet Park 20",
"postalCode": "0176",
"locality": "OSLO",
"countryCode": "no",
"country": "Norway"
},
"service": {
"id": 3,
"name": "Levert på dør kveld ",
"description": null,
"supplier": null,
"estimatedDelivery": null,
"price": 119.0,
"vat": 37.1875
},
"tracking": {
"mobile": null
}
},
"fulfillments": [{
"id": 10,
"status": "shipped",
"service": {
"id": 1,
"name": "consignor",
"trackingCode": null,
"referenceId": null,
"trackingUrl": null
},
"items": [{
"id": 11,
"productName": "Alpine Jacket",
"brandName": "PUMA",
"variantName": "Blue",
"size": "S",
"ean": 217445280878,
"quantity": 1,
"price": 299.0,
"vat": 59.8,
"total": 299.0,
"variant": {
"id": 1108,
"ean": 217445280878,
"name": "Blue",
"images": [{
"id": "products/u5k4pz8mhkns2drq6hcz",
"height": 1710,
"width": 1080
}],
"price": {
"retail": 2999.0,
"normal": 2999.0,
"discounted": 300.0,
"campaign": null,
"current": {
"type": 2,
"price": 300.0,
"vat": 60.0
},
"vat": 25.0
},
"size": "S",
"extArticleId": null,
"stock": {
"available": 0,
"threshold": 0
}
},
"product": {
"id": 1051,
"name": "Alpine Jacket",
"description": "Intern link: [Merker](/merker)\n\nEkstern link: [Google](http://google.com)",
"shortDescription": "Denne nye modellen fra Bjørn Dæhlie er laget i et 2-lags elastisk softshellmateriale",
"brand": {
"id": 1010,
"name": "PUMA",
"logo": {
"id": "0",
"width": null,
"height": null
}
},
"tags": ["AntonSportWebShopAPI.Models.Tag", "AntonSportWebShopAPI.Models.Tag", "AntonSportWebShopAPI.Models.Tag"],
"packageSize": "Normal",
"currentPrice": 190.0,
"version": "AAAAAAAACyo=",
"createdAt": "2014-11-05T15:34:44.717+00:00",
"modifiedAt": "2014-11-24T20:44:01.533+00:00",
"createdBy": "0",
"modifiedBy": "0"
}
}],
"message": "Test kommentar"
}],
"returns": [],
"total": 418.0,
"vat": 96.9875,
"payment": {
"partial": null,
"id": 1,
"type": 1,
"price": 0.0,
"vat": 0.0,
"name": "Kortbetaling",
"details": {
"chargeId": "ch_14yMWNKYEVdyeGxGly0lCqvo"
},
"transactions": [{
"id": 7,
"type": "Authorize",
"transactionReference": "ch_14yMWNKYEVdyeGxGly0lCqvo",
"amount": 418.0
}]
},
"account": null,
"comments": null,
"createdAt": "2014-11-13T12:16:19.887+00:00",
"modifiedAt": "2014-11-17T08:29:14.88+00:00",
"createdBy": "0",
"modifiedBy": "0"
}
Små komponenter
Komposisjon
Anton består av 300+ individuelle komponenter
Naturlig navngivning
Enkelt å navigere
Request & Response
Imitasjon av native apps
URL = Applikasjonsstate
Ruting skjema gir oversikt
<Route handler={Application}>
<Route path="products" handler={Products}>
<Route path=":product" handler={Product} />
<DefaultRoute handler={ProductList} />
</Route>
<Route path="checkout" handler={Checkout} />
</Route>
/products/flippin-snowboard
Application
Products
Product
/products
/
Application
Sidebar
Cart
cartItems
cartItems
Component
Data (props)
onAddCartItem
onUpdateCartItem
onRemoveCartItem
onAddCartItem
onUpdateCartItem
onRemoveCartItem
onAddCartItem
onUpdateCartItem
onRemoveCartItem
cartItems
Methods (props)
Product
Cart
Category
Cart
Component
getItems
getTotal
etc.
Cart
Component
Action
Flux
Reflux
Relay & GraphQL
var Product = require('../Product')
var Actions = require('../Actions')
describe('Add to cart button', function() {
it('should fire an add to cart action when clicked', function() {
var props = {id: 1}
var component = ReactTest.renderIntoDocument(Product(props))
var button = ReactTest.findComponentWithClass(component, 'add-to-cart')
ReactTest.Simulate.click(button)
expect(Actions.addToCart).toBeCalledWith({productId: 1})
})
})
Testing av et komponent
Bundling av scripts, styles og assets
Splitting og dynamisk lasting av bundles
Multi-device testing
React Hot Module Loading
Transpiling ES6, JSX etc. via Babel
Live Demo (#YOLO)
ReactCSSTransitionGroup
ReactTransitionGroup
AnimationMixin
Cheng Lou
react-tween-state, react-state-stream
Start tidlig med ruting
Hold komponenter små (composition)
Sentraliser datahåndtering
Frakoble brukerinteraksjoner med actions
Gjenbruk server og klient kode, få ytelse gratis!
Fortsatt noen ting som er knotete (animasjoner og CSS)
Simen Brekken (@simenbrekken)
Daniel Mahal (@danielmahal)
github.com/simenbrekken