SlideShare a Scribd company logo
redux vs alt
@uldissturms
objectives
compare redux and alt:
• concepts
• testing
• trends
agenda
• why?
• react
• flux
• redux and alt comparison
• microservices for client side
why?
quality takes time
quality
time
fb contact list
react
• just the UI
• virtual DOM
• one way data flow
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
ReactDOM.render(<HelloMessage name="John" />, mountNode); Hello John
fb chat
flux
Flux is the application architecture that Facebook uses for building client-side web
applications. It complements React and is more of a pattern than a framework.
redux and alt
• implementations of flux
• isomorphic - (equal shape when rendered both on client and server
side)
• support react-native
redux
• whole state of app is stored in an object tree inside a single store
• only way to change the state tree is to emit an action, an object
describing what happened
• to specify how the actions transform the state tree, you write pure
reducers
• great documentation - not that it needs one really
predictable state container for JavaScript apps
alt
• pure flux
• *actively* maintained
• extremely flexible and *unopinionated* in how you use flux
• has logo
• lacks up to date documentation and samples
Isomorphic flux implementation
hello world
!"" app.jsx
!"" components
#   !"" greet.jsx
#   !"" hello.jsx
#   !"" hello.test.js
#   $"" helloList.jsx
!"" index.html
!"" index.js
!"" state
#   !"" namesReducer.js
#   !"" namesReducer.test.js
#   $"" store.js
!"" actions
#   $"" NamesActions.js
!"" alt.js
!"" components
#   !"" greet.jsx
#   !"" hello.jsx
#   !"" hello.test.js
#   $"" helloList.jsx
!"" index.html
!"" index.js
!"" state
#   !"" configureNamesStore.js
#   !"" configureNamesStore.test.js
#   $"" namesStore.js
components
• similar or equal setup for tiny components
• differs for larger components that contain actions and more logic
• testing is easy using react test utils or wrapper libraries
• redux - allows function syntax, alt - can get messy when static
functions needed
components - code
import React from 'react';
const Hello = ({name}) => {
return (
<div>
Hello, <b class='test-name'>{name}</b>
</div>
);
};
export default Hello;
components - tests
describe('hello component', () => {
it('renders name', () => {
const output = renderHello('Steve');
const name = getChildrenByClass(output, 'test-name');
expect(name.props.children).toEqual('Steve');
});
it('renders component', () => {
const output = renderHello('Steve');
const expected =
<div>Hello, <b class="test-name">Steve</b></div>;
expect(output).toEqualJSX(expected);
});
});
const renderHello = name => {
const renderer = TestUtils.createRenderer();
renderer.render(<Hello name={name}/>);
return renderer.getRenderOutput();
}
components - tests
describe('<MyComponent />', () => {
it('renders three <Foo /> components', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.find(Foo)).to.have.length(3);
});
it('renders an `.icon-star`', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.find('.icon-star')).to.have.length(1);
});
it('renders children when passed in', () => {
const wrapper = shallow(
<MyComponent>
<div className="unique" />
</MyComponent>
);
expect(wrapper.contains(<div className="unique" />)).to.equal(true);
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = shallow(
<Foo onButtonClick={onButtonClick} />
);
wrapper.find('button').simulate('click');
expect(onButtonClick.calledOnce).to.equal(true);
});
});
airbnb/enzyme
react element
css class
html element
simulate event
stores
• redux - one, alt - many
• redux - registers reducers, alt - defines logic to execute based on data
passed by action
• redux - no tests needed, test reducers, alt - the meat of logic, harder to test
without side effects
• redux - immutable, alt - mutable
• alt - ReferenceError: A store named NamesStore already exists, double
check your store names or pass in your own custom identifier for each store]
stores - code
import alt from '../alt';
import namesActions from '../actions/NamesActions';
class NamesStore {
constructor() {
this.bindListeners({ add: namesActions.ADD})
this.state = {
names: []
}
}
add(name) {
if (name === 'Stranger') {
return this.state;
}
this.setState({ names: [...this.state.names, name] });
}
}
export default function configureStore() {
return alt.createStore(NamesStore, 'NamesStore');
}
stores - tests
import alt from '../alt';
import configureStore from './configureNamesStore';
import namesActions from '../actions/NamesActions';
const greet = name => {
const action = namesActions.ADD;
const data = name;
alt.dispatcher.dispatch({ action, data });
};
describe('store', () => {
it('starts off with empty names array', () => {
const store = configureStore();
const state = store.getState();
expect(state).toEqual({ names: []});
});
it('adds a name after greet action processed', () => {
const store = configureStore();
greet('Steve');
const state = store.getState();
expect(state).toEqual({ names: ['Steve']});
});
});
reducers
• pure functions - zero side-effects, only rely on parameter values
• super easy to test
• they scale - easy to add a new one
reducers - code
const shouldGreet = name => {
return name !== 'Stranger';
};
const namesReducer = (state = { names: [] }, action) => {
if (action.type === 'GREET' && shouldGreet(action.payload.name)) {
return { names: [...state.names, action.payload.name] };
}
return state;
};
export default namesReducer;
reducers - tests
import expect from 'expect';
import namesReducer from './namesReducer';
const greet = name => {
return { type: 'GREET', payload: { name: name }};
};
describe('names reducer', () => {
it('greets', () => {
const state = namesReducer({ names: [] }, greet('Steve'));
expect(state).toEqual({ names: ['Steve']});
});
it('no greetings to Stranger', () => {
const state = namesReducer({ names: [] }, greet('Stranger'));
expect(state).toEqual({ names: []});
});
});
react-redux glue
const store = configureStore();
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('App')
)
1
react-redux glue
import React from 'react';
import {connect} from 'react-redux';
import Hello from './hello';
const HelloList = ({ names }) => {
return (<div className='test-hello-name-list'>
{names.map(name =>
<Hello name={name}/>
)}
</div>);
}
const mapStateToProps = state => {
return {
names: state.names
}
}
export default connect(mapStateToProps)(HelloList);
2
react-alt glue
// Bad: getting into lib internals
import connectToStores from 'alt-utils/lib/connectToStores';
class HelloList extends React.Component {
static getStores(props) {
return [store];
}
static getPropsFromStores(props) {
return store.getState();
}
render() {
return (
<div className='test-hello-name-list'>
{this.props.names.map(name =>
<Hello name={name}/>
) }
</div>
);
}
}
export default connectToStores(HelloList);
1
react-alt glueclass Greet extends React.Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
static getStores(props) {
return [store]
}
static getPropsFromStores(props) {
return store.getState();
}
submit(e) {
e.preventDefault();
namesActions.add(this.input.value);
}
render() {
return (
<div className='test-greet'>
<form onSubmit={this.submit}>
<input id='test-greeting' type='text' ref={node => {
this.input = node}}/>
<button id='test-submit-greeting' type='submit'>Greet</button>
</form>
</div>
);
}
};
export default connectToStores(Greet);
1
application stats
35 ./hello-alt/components/greet.jsx
11 ./hello-alt/components/hello.jsx
32 ./hello-alt/components/hello.test.js
25 ./hello-alt/components/helloList.jsx
20 ./hello-alt/state/configureNamesStore.js
24 ./hello-alt/state/configureNamesStore.test.js
2 ./hello-alt/state/namesStore.js
8 ./hello-alt/actions/NamesActions.js
4 ./hello-alt/alt.js
12 ./hello-alt/index.js
21 ./hello-redux/components/greet.jsx
11 ./hello-redux/components/hello.jsx
32 ./hello-redux/components/hello.test.js
12 ./hello-redux/components/helloList.jsx
6 ./hello-redux/state/store.js
12 ./hello-redux/state/namesReducer.js
17 ./hello-redux/state/namesReducer.test.js
19 ./hello-redux/app.jsx
14 ./hello-redux/index.js
lines of code
144 total 173 total = 20 % more
scaling application
react alt
store
reducer
reducer
reducer
store
store
store
stats
redux alt
version 3.5.2 0.18.4
size 5.9K (2kb?) 23K
downloads / month 670K 38K
repo reactjs/redux goatslacker/alt
open issues 44 79
pull requests 20 4
last commit hours ago almost a month ago
comparison
redux alt
Open Systems Don't Always Win - Steve Jobs
verdict
TRIAL
Redux is a great, mature tool that has helped many of our teams reframe how they
think about managing state in client-side apps. Using a Flux-style approach, it enables
a loosely coupled state-machine architecture that's easy to reason about. We've found
it a good companion to some of our favored JavaScript frameworks, such as Ember
and React - ThoughtWorks TechRadar 2016 April
HOLD
Alt although says to be unopinionated it pushes to use action objects, static functions
that are used to connect components to stores, possible to mutate store state and
having multiple stores might encourage a monolith approach, doesn’t have as big
community backing as Redux and feels dated in comparison
end to end tests
var process = require('process');
var port = process.env.PORT;
function navigateToSite(test) {
return test.open('http://localhost:' + port);
}
module.exports = {
'says hello': function (test) {
navigateToSite(test)
.assert.doesntExist('.test-name', 'initial state has no greetings')
.type('#test-greeting', 'Steve')
.click('#test-submit-greeting')
.assert.text('.test-hello', 'Hello, Steve', 'adds a new greeting')
.done();
}
};
give confidence when switching frameworks
*don’t use dalekjs
example site - TES Global
microservices
https://www.youtube.com/watch?v=_SoPZS7Wqiw
one way to implement
implementation by TES Global
– Antoine de Saint Exupéry
It seems that perfection is attained, not when there is nothing more
to add, but when there is nothing more to take away
q&a
links
• http://redux.js.org
• http://alt.js.org
• https://github.com/airbnb/enzyme
• https://egghead.io/series/react-testing-cookbook
• https://egghead.io/series/getting-started-with-redux
• http://redux.js.org/docs/recipes/WritingTests.html
• https://github.com/gaearon/redux-devtools
• https://github.com/uldissturms/talks

More Related Content

PPTX
PDF
Switch to React.js from AngularJS developer
PPTX
Redux training
PDF
React state managmenet with Redux
PPTX
Academy PRO: React JS. Redux & Tooling
PPTX
React & redux
PDF
Intro to ReactJS
PDF
React, Redux, ES2015 by Max Petruck
Switch to React.js from AngularJS developer
Redux training
React state managmenet with Redux
Academy PRO: React JS. Redux & Tooling
React & redux
Intro to ReactJS
React, Redux, ES2015 by Max Petruck

What's hot (20)

PDF
React JS and Redux
PPTX
React + Redux Introduction
PPTX
Better web apps with React and Redux
PPTX
ReactJs presentation
PDF
React & Redux
PPTX
React / Redux Architectures
PPTX
Getting started with ReactJS
PPTX
PDF
Introduction to React & Redux
PDF
React for Dummies
PDF
React & Redux
PPTX
Introduction to react and redux
PDF
React redux
PDF
React + Redux. Best practices
PPTX
React, Flux and a little bit of Redux
PDF
React.js or why DOM finally makes sense
PDF
Let's Redux!
PPTX
ProvJS: Six Months of ReactJS and Redux
PDF
React.js and Redux overview
PPTX
React with Redux
React JS and Redux
React + Redux Introduction
Better web apps with React and Redux
ReactJs presentation
React & Redux
React / Redux Architectures
Getting started with ReactJS
Introduction to React & Redux
React for Dummies
React & Redux
Introduction to react and redux
React redux
React + Redux. Best practices
React, Flux and a little bit of Redux
React.js or why DOM finally makes sense
Let's Redux!
ProvJS: Six Months of ReactJS and Redux
React.js and Redux overview
React with Redux
Ad

Viewers also liked (9)

PPTX
Reducers+flux=redux
PDF
Designing applications with Redux
PPTX
Flux and redux
PPTX
React. Flux. Redux
PDF
Migrating from Flux to Redux. Why and how.
PPTX
005. a React project structure
PDF
NDC 2015 이광영 [야생의 땅: 듀랑고] 전투 시스템 개발 일지
PDF
Building React Applications with Redux
PDF
중앙 서버 없는 게임 로직
Reducers+flux=redux
Designing applications with Redux
Flux and redux
React. Flux. Redux
Migrating from Flux to Redux. Why and how.
005. a React project structure
NDC 2015 이광영 [야생의 땅: 듀랑고] 전투 시스템 개발 일지
Building React Applications with Redux
중앙 서버 없는 게임 로직
Ad

Similar to Redux vs Alt (20)

PDF
React lecture
PDF
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
PPTX
Building complex User Interfaces with Sitecore and React
PDF
React nocojs
KEY
Unit testing zend framework apps
PDF
Advanced redux
PDF
Dive into React Performance
PDF
React 101
PDF
Full Stack Toronto - the 3R Stack
PDF
Unit testing with zend framework tek11
PDF
React table tutorial project setup, use table, and usefilter
KEY
Unit testing with zend framework PHPBenelux
PDF
Stay with React.js in 2020
PPTX
React & Redux for noobs
PDF
Reactивная тяга
PDF
Connect.js - Exploring React.Native
PDF
Writing testable js [by Ted Piotrowski]
PDF
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
PDF
Understanding backbonejs
PPTX
React/Redux
React lecture
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
Building complex User Interfaces with Sitecore and React
React nocojs
Unit testing zend framework apps
Advanced redux
Dive into React Performance
React 101
Full Stack Toronto - the 3R Stack
Unit testing with zend framework tek11
React table tutorial project setup, use table, and usefilter
Unit testing with zend framework PHPBenelux
Stay with React.js in 2020
React & Redux for noobs
Reactивная тяга
Connect.js - Exploring React.Native
Writing testable js [by Ted Piotrowski]
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Understanding backbonejs
React/Redux

Recently uploaded (20)

PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Introduction to Artificial Intelligence
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
AI in Product Development-omnex systems
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Digital Strategies for Manufacturing Companies
PPT
Introduction Database Management System for Course Database
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
ISO 45001 Occupational Health and Safety Management System
CHAPTER 2 - PM Management and IT Context
Understanding Forklifts - TECH EHS Solution
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PTS Company Brochure 2025 (1).pdf.......
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Introduction to Artificial Intelligence
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
AI in Product Development-omnex systems
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Digital Strategies for Manufacturing Companies
Introduction Database Management System for Course Database
How Creative Agencies Leverage Project Management Software.pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Odoo Companies in India – Driving Business Transformation.pdf
Softaken Excel to vCard Converter Software.pdf
Odoo POS Development Services by CandidRoot Solutions
ISO 45001 Occupational Health and Safety Management System

Redux vs Alt

  • 2. objectives compare redux and alt: • concepts • testing • trends
  • 3. agenda • why? • react • flux • redux and alt comparison • microservices for client side
  • 6. react • just the UI • virtual DOM • one way data flow var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } }); ReactDOM.render(<HelloMessage name="John" />, mountNode); Hello John
  • 8. flux Flux is the application architecture that Facebook uses for building client-side web applications. It complements React and is more of a pattern than a framework.
  • 9. redux and alt • implementations of flux • isomorphic - (equal shape when rendered both on client and server side) • support react-native
  • 10. redux • whole state of app is stored in an object tree inside a single store • only way to change the state tree is to emit an action, an object describing what happened • to specify how the actions transform the state tree, you write pure reducers • great documentation - not that it needs one really predictable state container for JavaScript apps
  • 11. alt • pure flux • *actively* maintained • extremely flexible and *unopinionated* in how you use flux • has logo • lacks up to date documentation and samples Isomorphic flux implementation
  • 12. hello world !"" app.jsx !"" components #   !"" greet.jsx #   !"" hello.jsx #   !"" hello.test.js #   $"" helloList.jsx !"" index.html !"" index.js !"" state #   !"" namesReducer.js #   !"" namesReducer.test.js #   $"" store.js !"" actions #   $"" NamesActions.js !"" alt.js !"" components #   !"" greet.jsx #   !"" hello.jsx #   !"" hello.test.js #   $"" helloList.jsx !"" index.html !"" index.js !"" state #   !"" configureNamesStore.js #   !"" configureNamesStore.test.js #   $"" namesStore.js
  • 13. components • similar or equal setup for tiny components • differs for larger components that contain actions and more logic • testing is easy using react test utils or wrapper libraries • redux - allows function syntax, alt - can get messy when static functions needed
  • 14. components - code import React from 'react'; const Hello = ({name}) => { return ( <div> Hello, <b class='test-name'>{name}</b> </div> ); }; export default Hello;
  • 15. components - tests describe('hello component', () => { it('renders name', () => { const output = renderHello('Steve'); const name = getChildrenByClass(output, 'test-name'); expect(name.props.children).toEqual('Steve'); }); it('renders component', () => { const output = renderHello('Steve'); const expected = <div>Hello, <b class="test-name">Steve</b></div>; expect(output).toEqualJSX(expected); }); }); const renderHello = name => { const renderer = TestUtils.createRenderer(); renderer.render(<Hello name={name}/>); return renderer.getRenderOutput(); }
  • 16. components - tests describe('<MyComponent />', () => { it('renders three <Foo /> components', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find(Foo)).to.have.length(3); }); it('renders an `.icon-star`', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find('.icon-star')).to.have.length(1); }); it('renders children when passed in', () => { const wrapper = shallow( <MyComponent> <div className="unique" /> </MyComponent> ); expect(wrapper.contains(<div className="unique" />)).to.equal(true); }); it('simulates click events', () => { const onButtonClick = sinon.spy(); const wrapper = shallow( <Foo onButtonClick={onButtonClick} /> ); wrapper.find('button').simulate('click'); expect(onButtonClick.calledOnce).to.equal(true); }); }); airbnb/enzyme react element css class html element simulate event
  • 17. stores • redux - one, alt - many • redux - registers reducers, alt - defines logic to execute based on data passed by action • redux - no tests needed, test reducers, alt - the meat of logic, harder to test without side effects • redux - immutable, alt - mutable • alt - ReferenceError: A store named NamesStore already exists, double check your store names or pass in your own custom identifier for each store]
  • 18. stores - code import alt from '../alt'; import namesActions from '../actions/NamesActions'; class NamesStore { constructor() { this.bindListeners({ add: namesActions.ADD}) this.state = { names: [] } } add(name) { if (name === 'Stranger') { return this.state; } this.setState({ names: [...this.state.names, name] }); } } export default function configureStore() { return alt.createStore(NamesStore, 'NamesStore'); }
  • 19. stores - tests import alt from '../alt'; import configureStore from './configureNamesStore'; import namesActions from '../actions/NamesActions'; const greet = name => { const action = namesActions.ADD; const data = name; alt.dispatcher.dispatch({ action, data }); }; describe('store', () => { it('starts off with empty names array', () => { const store = configureStore(); const state = store.getState(); expect(state).toEqual({ names: []}); }); it('adds a name after greet action processed', () => { const store = configureStore(); greet('Steve'); const state = store.getState(); expect(state).toEqual({ names: ['Steve']}); }); });
  • 20. reducers • pure functions - zero side-effects, only rely on parameter values • super easy to test • they scale - easy to add a new one
  • 21. reducers - code const shouldGreet = name => { return name !== 'Stranger'; }; const namesReducer = (state = { names: [] }, action) => { if (action.type === 'GREET' && shouldGreet(action.payload.name)) { return { names: [...state.names, action.payload.name] }; } return state; }; export default namesReducer;
  • 22. reducers - tests import expect from 'expect'; import namesReducer from './namesReducer'; const greet = name => { return { type: 'GREET', payload: { name: name }}; }; describe('names reducer', () => { it('greets', () => { const state = namesReducer({ names: [] }, greet('Steve')); expect(state).toEqual({ names: ['Steve']}); }); it('no greetings to Stranger', () => { const state = namesReducer({ names: [] }, greet('Stranger')); expect(state).toEqual({ names: []}); }); });
  • 23. react-redux glue const store = configureStore(); render( <Provider store={store}> <App /> </Provider>, document.getElementById('App') ) 1
  • 24. react-redux glue import React from 'react'; import {connect} from 'react-redux'; import Hello from './hello'; const HelloList = ({ names }) => { return (<div className='test-hello-name-list'> {names.map(name => <Hello name={name}/> )} </div>); } const mapStateToProps = state => { return { names: state.names } } export default connect(mapStateToProps)(HelloList); 2
  • 25. react-alt glue // Bad: getting into lib internals import connectToStores from 'alt-utils/lib/connectToStores'; class HelloList extends React.Component { static getStores(props) { return [store]; } static getPropsFromStores(props) { return store.getState(); } render() { return ( <div className='test-hello-name-list'> {this.props.names.map(name => <Hello name={name}/> ) } </div> ); } } export default connectToStores(HelloList); 1
  • 26. react-alt glueclass Greet extends React.Component { constructor(props) { super(props); this.submit = this.submit.bind(this); } static getStores(props) { return [store] } static getPropsFromStores(props) { return store.getState(); } submit(e) { e.preventDefault(); namesActions.add(this.input.value); } render() { return ( <div className='test-greet'> <form onSubmit={this.submit}> <input id='test-greeting' type='text' ref={node => { this.input = node}}/> <button id='test-submit-greeting' type='submit'>Greet</button> </form> </div> ); } }; export default connectToStores(Greet); 1
  • 27. application stats 35 ./hello-alt/components/greet.jsx 11 ./hello-alt/components/hello.jsx 32 ./hello-alt/components/hello.test.js 25 ./hello-alt/components/helloList.jsx 20 ./hello-alt/state/configureNamesStore.js 24 ./hello-alt/state/configureNamesStore.test.js 2 ./hello-alt/state/namesStore.js 8 ./hello-alt/actions/NamesActions.js 4 ./hello-alt/alt.js 12 ./hello-alt/index.js 21 ./hello-redux/components/greet.jsx 11 ./hello-redux/components/hello.jsx 32 ./hello-redux/components/hello.test.js 12 ./hello-redux/components/helloList.jsx 6 ./hello-redux/state/store.js 12 ./hello-redux/state/namesReducer.js 17 ./hello-redux/state/namesReducer.test.js 19 ./hello-redux/app.jsx 14 ./hello-redux/index.js lines of code 144 total 173 total = 20 % more
  • 29. stats redux alt version 3.5.2 0.18.4 size 5.9K (2kb?) 23K downloads / month 670K 38K repo reactjs/redux goatslacker/alt open issues 44 79 pull requests 20 4 last commit hours ago almost a month ago
  • 30. comparison redux alt Open Systems Don't Always Win - Steve Jobs
  • 31. verdict TRIAL Redux is a great, mature tool that has helped many of our teams reframe how they think about managing state in client-side apps. Using a Flux-style approach, it enables a loosely coupled state-machine architecture that's easy to reason about. We've found it a good companion to some of our favored JavaScript frameworks, such as Ember and React - ThoughtWorks TechRadar 2016 April HOLD Alt although says to be unopinionated it pushes to use action objects, static functions that are used to connect components to stores, possible to mutate store state and having multiple stores might encourage a monolith approach, doesn’t have as big community backing as Redux and feels dated in comparison
  • 32. end to end tests var process = require('process'); var port = process.env.PORT; function navigateToSite(test) { return test.open('http://localhost:' + port); } module.exports = { 'says hello': function (test) { navigateToSite(test) .assert.doesntExist('.test-name', 'initial state has no greetings') .type('#test-greeting', 'Steve') .click('#test-submit-greeting') .assert.text('.test-hello', 'Hello, Steve', 'adds a new greeting') .done(); } }; give confidence when switching frameworks *don’t use dalekjs
  • 33. example site - TES Global
  • 35. one way to implement implementation by TES Global
  • 36. – Antoine de Saint Exupéry It seems that perfection is attained, not when there is nothing more to add, but when there is nothing more to take away q&a
  • 37. links • http://redux.js.org • http://alt.js.org • https://github.com/airbnb/enzyme • https://egghead.io/series/react-testing-cookbook • https://egghead.io/series/getting-started-with-redux • http://redux.js.org/docs/recipes/WritingTests.html • https://github.com/gaearon/redux-devtools • https://github.com/uldissturms/talks