Download - Nate Abele "Un-Dux Your Front-End"
![Page 1: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/1.jpg)
Un-Dux Your Front-EndNate AbeleAdvisor Innovation Labs
![Page 2: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/2.jpg)
UN-DUX YOUR FRONT-ENDNATE ABELE
![Page 3: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/3.jpg)
THE UNREASONABLE EFFECTIVENESS OF DATA
OR…
![Page 4: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/4.jpg)
UN-DUX YOUR FRONT-END
YOUR HOST: NATE ABELE
▸ Some PHP frameworks (Li3, CakePHP)
▸ AngularUI Router
▸ Architect @ AI Labs
▸ @nateabele
![Page 5: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/5.jpg)
UN-DUX YOUR FRONT-END
ADVISOR INNOVATION LABS
![Page 6: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/6.jpg)
CONCEPTS
![Page 7: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/7.jpg)
![Page 8: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/8.jpg)
CONCEPTS
![Page 9: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/9.jpg)
![Page 10: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/10.jpg)
![Page 11: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/11.jpg)
![Page 12: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/12.jpg)
![Page 13: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/13.jpg)
![Page 14: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/14.jpg)
STATE
![Page 15: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/15.jpg)
![Page 16: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/16.jpg)
< Component />
![Page 17: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/17.jpg)
< Component />
< Component /> < Component />
![Page 18: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/18.jpg)
< Component />
< Component /> < Component />
< Component />
![Page 19: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/19.jpg)
< Component />
< Component /> < Component />
< Component /> < Component /> < Component />
![Page 20: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/20.jpg)
< Component />
< Component /> < Component />
< Component /> < Component /> < Component />
![Page 21: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/21.jpg)
< Component />
< Component /> < Component />
< Component /> < Component /> < Component />
![Page 22: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/22.jpg)
< Component />
< Component /> < Component />
< Component /> < Component /> < Component />
![Page 23: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/23.jpg)
![Page 24: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/24.jpg)
UN-DUX YOUR FRONT-END
REDUX
▸ Single-value store
▸ Changes (actions) are simple values
▸ Few opinions
![Page 25: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/25.jpg)
SETTING UP
$ yarn add
![Page 26: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/26.jpg)
SETTING UP
$ yarn add reduxreact-reduxreact-router-reduxredux-loggerredux-sagaredux-mock-storeredux-immutableredux-thunkredux-promise-middlewarereact-redux-formredux-actredux-saga-test-planredux-queryredux-saga-async...
![Page 27: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/27.jpg)
![Page 28: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/28.jpg)
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
![Page 29: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/29.jpg)
![Page 30: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/30.jpg)
ELMELM
![Page 31: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/31.jpg)
![Page 32: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/32.jpg)
CASIUM
![Page 33: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/33.jpg)
import React from 'react';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, ({ count }) => ({ count: count + 1 })], [Decrement, ({ count }) => ({ count: count - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 34: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/34.jpg)
![Page 35: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/35.jpg)
import React from 'react';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, ({ count }) => ({ count: count + 1 })], [Decrement, ({ count }) => ({ count: count - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 36: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/36.jpg)
import React from 'react';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, ({ count }) => ({ count: count + 1 })], [Decrement, ({ count }) => ({ count: count - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 37: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/37.jpg)
import React from 'react';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, ({ count }) => ({ count: count + 1 })], [Decrement, ({ count }) => ({ count: count - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 38: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/38.jpg)
RAMDAJS
![Page 39: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/39.jpg)
import React from 'react';import { evolve } from 'ramda';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, evolve({ count: ct => ct + 1 })], [Decrement, evolve({ count: ct => ct - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 40: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/40.jpg)
import React from 'react';import { evolve } from 'ramda';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, evolve({ count: ct => ct + 1 })], [Decrement, evolve({ count: ct => ct - 1 })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 41: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/41.jpg)
import React from 'react';import { evolve, inc, dec } from 'ramda';
import { container } from 'casium';import Message from 'casium/message';
class Increment extends Message {}class Decrement extends Message {}
export default container({
init: () => ({ count: 0 }),
update: [ [Increment, evolve({ count: inc })], [Decrement, evolve({ count: dec })] ],
view: ({ emit, count }) => ( <div> <button onClick={emit(Decrement)}> - </button> { count } <button onClick={emit(Increment)}> + </button> </div> )});
![Page 42: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/42.jpg)
import { merge } from 'ramda';/* … */
class UpdateForm extends Message {}class SignIn extends Message {}
export default container({ init: () => ({ email: '', password: '' }),
update: [[UpdateForm,(model, { key, value }) => merge(model, { [key]: value })
]],
view: ({ emit, email, password }) => ( <form> <input type='email' value={email}
onChange={emit([UpdateForm, { key: 'email' }])} /> <input type='password' value={password}
onChange={emit([UpdateForm, { key: 'password' }])} /> </form> )});
![Page 43: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/43.jpg)
import { Http } from 'casium/commands';/* … */
class SignIn extends Message {}class SignInSuccess extends Message {}class SignInError extends Message {}
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ [UpdateForm, (model, { key, value }) => /* … */],
[SignIn, model => [merge(model, { loading: true }),new Http.Post({url: '/login',data: { email: model.email, password: model.password },result: SignInSuccess,error: SignInError
})]]
],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignIn)}> /* … */ </form> )});
![Page 44: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/44.jpg)
import { Http } from 'casium/commands';/* … */
class SignInSuccess extends Message {}class SignInError extends Message {}
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ /* … */
[SignInSuccess, (model, { data }) => /* Handle the response… */][SignInError, (model, { status }) => /* Handle error… */]
],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignIn)}> /* … */ </form> )});
![Page 45: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/45.jpg)
import { Post, formData } from 'casium/commands/http';
export default class SignIn extends Post {
constructor({ email, password, ...params }) { const id = 'my-app', secret = 'woo-sekrit';
super({ url: '/oauth/token', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic ' + btoa(id + ':' + secret) }, data: formData({ username: email, password, grant_type: 'password', scope: 'read write', client_secret: secret, client_id: id }), ...params }); }}
![Page 46: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/46.jpg)
import { Post, formData } from 'casium/commands/http';import { SignInSuccess, SignInError } from './sign_in_container';
export default class SignIn extends Post {
constructor({ email, password, ...params }) { const id = 'my-app', secret = 'woo-sekrit';
super({ url: '/oauth/token', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic ' + btoa(id + ':' + secret) }, data: formData({ username: email, password, grant_type: 'password', scope: 'read write', client_secret: secret, client_id: id }),
result: SignInSuccess,error: SignInError
...params }); }}
![Page 47: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/47.jpg)
import { Http } from 'casium/commands';/* … */
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ /* … */
[SignInSubmit, model => [merge(model, { loading: true }),new Http.Post({url: '/login',data: { email: model.email, password: model.password },result: SignInSuccess,error: SignInError
})]]
],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignInSubmit)}> /* … */ </form> )});
![Page 48: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/48.jpg)
import { SignIn } from ‘./messages/sign_in’;/* … */
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ /* … */
[SignInSubmit, model => [merge(model, { loading: true }),new SignIn({ email: model.email, password: model.password })
]] ],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignInSubmit)}> /* … */ </form> )});
![Page 49: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/49.jpg)
import { SignIn } from ‘./messages/sign_in’;import { container, seq } from 'casium';/* … */
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ /* … */
[SignInSubmit, seq(model => merge(model, { loading: true }),model => [model, new SignIn({ email: model.email, password: model.password})]
)] ],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignInSubmit)}> /* … */ </form> )});
![Page 50: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/50.jpg)
import { merge, pick } from 'ramda';import { SignIn } from ‘./messages/sign_in’;import { container, seq, replace, commands } from 'casium';/* … */
export default container({ init: () => ({ email: '', password: '', loading: false }),
update: [ /* … */
[SignInSubmit, seq(replace({ loading: true }),commands(SignIn, pick(['email', 'password']))
)] ],
view: ({ emit, email, password }) => ( <form onSubmit={emit(SignInSubmit)}> /* … */ </form> )});
![Page 51: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/51.jpg)
WHY?
![Page 52: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/52.jpg)
GUARANTEES
![Page 53: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/53.jpg)
EXAMPLE: PROMISES
![Page 54: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/54.jpg)
GUARANTEES
![Page 55: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/55.jpg)
‘PROBABLY’
![Page 56: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/56.jpg)
$ git checkout b69c907
![Page 57: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/57.jpg)
$ yarn test
![Page 58: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/58.jpg)
![Page 59: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/59.jpg)
[DEMO]
![Page 60: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/60.jpg)
UN-DUX YOUR FRONT-END
REVIEW
▸ Diff view of changes
▸ Generated unit tests
▸ Time travel
▸ Message log export
▸ Websockets magic
![Page 61: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/61.jpg)
UN-DUX YOUR FRONT-END
IMPLICATIONS
▸ Crossing boundaries
▸ Device farm
▸ Reproduce production errors
▸ Watch / replay user sessions
▸ Isolation
▸ Browser testing
▸ API testing
![Page 62: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/62.jpg)
UN-DUX YOUR FRONT-END
IMPLICATIONS
▸ Diff analysis
![Page 63: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/63.jpg)
UN-DUX YOUR FRONT-END
Sign Up.json
Log In.json
Set Prefs.json
![Page 64: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/64.jpg)
UN-DUX YOUR FRONT-END
Sign Up.json
Log In.json
Set Prefs.json
![Page 65: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/65.jpg)
$ webpack my-app.js
![Page 66: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/66.jpg)
$ webpack my-app.js> my-app-df3db62731a0a32ef0c6.js
![Page 67: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/67.jpg)
UN-DUX YOUR FRONT-END
df3db6273+
![Page 68: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/68.jpg)
UN-DUX YOUR FRONT-END
Sign Up.json
Log In.json
+
+
df3db6273
df3db6273
![Page 69: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/69.jpg)
UN-DUX YOUR FRONT-END
TRY CASIUM
▸ /ai-labs-team/casium
▸ /ai-labs-team/casium-devtools
▸ casium.io
![Page 70: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/70.jpg)
THANKS!
![Page 71: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/71.jpg)
QUESTIONS?
![Page 73: Nate Abele "Un-Dux Your Front-End"](https://reader031.vdocuments.net/reader031/viewer/2022030317/5a64fdee7f8b9a2e118b472d/html5/thumbnails/73.jpg)
PHOTO CREDITS
▸ ‘This is not a pipe’: https://www.threadless.com/product/543/this_is_not_a_pipe
▸ ‘Cow’: https://www.emaze.com/@AWCTOFZ
▸ ‘Steak’: http://www.chicagomeat.com/products/t-bone-steak/
▸ ‘McDonald’s Hamburger’: https://www.businessinsider.com.au/man-saves-mcdonalds-burger-for-5-years-2014-7
▸ ‘Texas’: http://yalsa.ala.org/blog/2014/02/25/virtual-road-trip-texas-part-2/
▸ ‘DeLorean’: https://www.pinterest.com/pin/114419646753355072/
▸ ‘Redux Architecture’: https://medium.com/mofed/react-redux-architecture-overview-7b3e52004b6e