daniel graham phd redux/flux a new look at … · 2020. 3. 18. · redux simply checks whether the...
TRANSCRIPT
R E D U X / F L U X A N E W L O O K AT A R C H I T E C T U R E
D A N I E L G R A H A M P H D
A R C H I T E C T U R E S F O R D E A L I N G W I T H D ATA F L O W
B A C K G R O U N D S O F T W A R E A R C H I T E C T U R E S
M O D E L
V I E W
C O N T R O L E R
U S E R
M V C S T E P S
https://www.slideshare.net/SrinathRamamoorthi/introduction-to-django-48976864
A LT E R N AT I V E A R C H I T E C T U R E S
Java (AWT/Swing/SWT)ASP.net Django
Angular
Android
F U N N Y ? S H O U L D D J A N G O B E C A L L E D M T V ?
https://www.slideshare.net/SrinathRamamoorthi/introduction-to-django-48976864
S H A L L O W D I V E I N T O M V C
• Model describes the data
public class Person { public int PersonId { get; set; }
[Required] [MinLength(2)] public string Name { get; set; }
[Phone] public string PhoneNumber { get; set; }
[EmailAddress] public string Email { get; set; } }
Create clean model classes and easily bind them to your database.
PersonId Name PhoneNumber Email
1 John 777 999 8888 Test
A P P L I C AT I O N W I T H
C O N T R O L L E R
public class PeopleController : Controller { private readonly AddressBookContext _context;
public PeopleController(AddressBookContext context) { _context = context; }
// GET: /people public async Task Index() { return View(await _context.People.ToListAsync()); }
// GET: /people/details/5 public async Task Details(int id) { var person = await _context.People.Find(id);
if (person == null) { return NotFound(); }
return View(person); } }
C O N T R O L E R
https://docs.microsoft.com/en-us/aspnet/core/mvc/views/overview?view=aspnetcore-2.2
V I E W
B A C K G R O U N D S O F T W A R E A R C H I T E C T U R E S
M O D E L
V I E W
C O N T R O L E R
U S E R
T H E P R O B L E M
M O D E L
V I E W
C O N T R O L E R
V I E W
V I E W
M O D E L
M O D E L
Does not work a scale. Became a problem at facebook.
D O W E R E A L LY H AV E P R O B L E M W E D ATA F L O W I N R E A C T A P P L I C AT I O N S ?
P R O P D R I L L I N G
Prop drilling (also called "threading") refers to the process you have to go
through to get data to parts of the React Component tree.
-Ken C. Dodds
1 function Toggle() { 2 const [on, setOn] = useState(false) 3 const toggle = () => setOn(o => !o) 4 return ( 5 <View> 6 <Text>The button is {on ? 'on' : 'off'}</Text> 7 <Button onPress={toggle}>Toggle</Button> 8 </View> 9 ) 10}
Simple Stateful Component
What would happen if we Created a switch component
1 function Toggle() { 2 const [on, setOn] = useState(false) 3 const toggle = () => setOn(o => !o) 4 return <Switch on={on} onToggle={toggle} /> 5 } 6 7 function Switch({on, onToggle}) { 8 return ( 9 <View> 10 <Text>The button is {on ? 'on' : 'off'}</Text> 11 <Button onClick={onToggle}>Toggle</Button> 12 </View> 13 ) 14 }
onToggle()
Toggle
<button. on>
Switch
What Happens if create custom button Custom Message Component?
on
1 function Toggle() { 2 const [on, setOn] = useState(false) 3 const toggle = () => setOn(o => !o) 4 return <Switch on={on} onToggle={toggle} /> 5 } 6 7function Switch({on, onToggle}) { 8 return ( 9 <View> 10 <SwitchMessage on={on} /> 11 <SwitchButton onToggle={onToggle} /> 12 </View> 13 ) 14} 15 16function SwitchMessage({on}) { 17 return <View>The button is {on ? 'on' : 'off'}</View> 18} 19 20function SwitchButton({onToggle}) { 21 return <Button onClick={onToggle}>Toggle</Button> 22}
onToggle()
Toggle
Switch
on
Switch Message Switch Button
FA C E B O O K P R O P O S E D F L U X
• An architecture approach that utilizes a unidirectional data flow.
Bill Fisher and Jing Chen
https://www.youtube.com/watch?v=i__969noyAM
2014
N E W P R O P O S E D A R C H I T E C T U R E
Data flows in one direction
A C T I O N
User triggers some action via
Javascript
D I S PAT C H E R S T O R E
Stores the data/models
V I E W
What the user sees
The central hub Gate Keeper
N E W P R O P O S E D A R C H I T E C T U R E
Data flows in one direction
A C T I O N D I S PAT C H E R S T O R E V I E W
A C T I O N
N E W P R O P O S E D A R C H I T E C T U R E
Data flows in one direction
A C T I O N D I S PAT C H E R S T O R E V I E W
A C T I O N
S T O R ES T O R E
V I E W
V IEW
R E D U X
R E D U X I S A N I M P L E M E N TAT I O N O F F L U X
A C T I O N S T O R E V I E W
A C T I O N
Dispatching an Action
Single store with single state
A C T I O N S T O R E V I E W
A C T I O N
Dispatching an Action
T H I N K I N G A B O U T R E D U C E I N T H E C O N T E X T O F R E A C T
Recall that state is local to the component
L E T ’ S B U I L D A M I N R E D U X
• First let’s think about a way to process all the action and update the store.
First we going need some way to combine the data that each action will pass to the store
G O A L : • Understand the redux architecture by designing a mini redux
• Our store is going to store the following simple state var exampleSate = { user:{displayName:" ", id: 1 }, preferences = [1,2,3], }
A C T I O N S T O R E V I E W
A C T I O N
A C T I O N S
• An action is a piece of data that contains the information required to update the state
S TA N D A R D F O R M AT F O R A C T I O N S
function updateUser(){ store.dispatch({displayName: “wahoo”, id: 12}) }
Example Action
var exampleSate = { user:{displayName:" ", id: 1 }, preferences = [1,2,3], }
B U I L D A S I M P L E R E D U C E R
reduce = (state, update)=>{ return ({...state, ...update}) } state = {}
state = reduce(state, {name:"Daniel"}) state = reduce(state, {age: 30}) console.log(state)
A C T I O N S T O R E
Updates are made using a pure (function)
Pure function result is deterministic given the same input it will produce the same output
(a, b)=>{ return a + b }
Redux simply checks whether the old object is the same as the new object by comparing the memory locations of the two objects. So if you mutate the old object’s property inside a reducer, the “new state” and the “old state” will both point to the same object. Hence Redux thinks nothing has changed! So this won’t work.
https://medium.freecodecamp.org/why-redux-needs-reducers-to-be-pure-functions-d438c58ae468
M U LT I P L E R E D U C E R S
• Consider a more complex global state.
• Involving both general user Info and Podcast data
var exampleSate = { userDisplayName:'DJ wacky ackee', preferences : [1,2,3], }
I N S T E A D O F H AV I N G A R E D U C E R P R O C E S S T H E W H O L E O B J E C T
H AV E R E D U C E R F O R J U S T T H E P R E F E R E N C E S
M U LT I P L E R E D U C E R S
/** * Reducer that just updates the user */ preferencesReducer = (state, update)=>{ return [...state, update ] }
reduce = (state, update)=>{ return ({...state, ...update}) }
var exampleSate = { user:{displayName:" ", id: 1 }, preferences : [1,2,3], }
A C T I O N T E M P L AT E D
{ type: 'ADD_TODO', payload: { text: 'Do something.' } }
Action Template
Update USER
{ type: ‘UPDATE_USER’, payload: { user: {displayName: ‘DJ’} } }
{ type: ‘UPDATE_PREFERENCES’, payload: { preferences: [1,2] } }
Update preferences
A C T I O N S T O R E V I E W
https://github.com/redux-utilities/flux-standard-
action
T O P L E V E L R E D U C E R
{ type: 'ADD_TODO', payload: { text: 'Do something.' } }
Action Template
Update USER
{ type: ‘UPDATE_USER’, payload: { user: {displayName: ‘DJ’} } }
{ type: ‘UPDATE_PREFERENCES’, payload: { preferences: [1,2] } }
Update preferences
/** * Top Level reducer */ reducer = (state, update)=>{ if(update.type==="UPDATE_PREFERENCES"){ state.preferences = preferencesReducer(state.preferences, ...update.payload) } if(update.type==="UPDATE_USER"){ state.user = userReducer(state.user, update.payload) } return state }
{ type: “UPDATE_USER”, payload:{ user: {display: “wahoo”, id: 12} } }
S T O R E
• Responsible for maintain state
• Expose getter getState()
• Updated via dispatch Method
• Support the listens for state changes.
class Store{ constructor(reducer, initialState){ this.reducer = reducer this.state = initialState }
getState(){ return this.state; }
dispatch(update){ this.state = this.reducer(update, this.state) return this.state }
}
var s = new Store(reduce, {}) console.log(s.getState()) s.dispatch({uva: "wahoo"}) console.log(s.getState())
PA S S I N G T H E R E D U C E R F U N C T I O N
R E A C T R E D U X F L O W
W E B