Last active
October 10, 2018 19:22
-
-
Save leofavre/e6c2fcef14e20755da84f9524649c84c to your computer and use it in GitHub Desktop.
Front-End concepts from React and Redux applied to web components
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DUMB COMPONENT | |
// a *pure* function that renders a stateless component. | |
const UserView = (args) => html` | |
<div> | |
<h4>${args.firstName} ${args.lastName}</h4> | |
<p>Requests: <strong>${args.requests}</strong></p> | |
</div> | |
`; | |
// SMART COMPONENT | |
// a component the handles state and passes it to the dumb component to render. | |
class User extends HTMLElement { | |
constructor() { | |
super(); | |
this.state = { | |
// ... some initial state | |
} | |
} | |
connectedCallback() { | |
// ... component logic | |
} | |
render() { | |
return html`${UserView(this)}`; | |
} | |
} | |
// STATE | |
// a description of the state of an application or a component. | |
const state = { | |
firstName: 'Leonardo', | |
lastName: 'Favre', | |
requests: 3, | |
}; | |
// SELECTOR | |
// a *pure* function that computes some data based *only* on the state. | |
const getFullName = state => `${state.firstName} ${state.lastName}`; | |
// REDUCER | |
// a *pure* function that receives an state and an action | |
// and then returns the next state. | |
// the reducer does *NOT* deep clone. | |
const reducer = (state = {}, action = {}) => { | |
switch (action.type) { | |
case 'SET_FIRST_NAME': | |
return { | |
...state, | |
firstName: action.firstName | |
}; | |
case 'SET_LAST_NAME': | |
return { | |
...state, | |
lastName: action.lastName | |
}; | |
case 'INCREMENT_REQUEST': | |
return { | |
...state, | |
requests: (state.requests || 0) + 1 | |
}; | |
default: | |
return state; | |
} | |
} | |
// ACTIONS | |
// a set of functions, not necessarily *pure*, | |
// that request a change for the reducer. | |
const setFirstName = firstName => ({ | |
firstName, | |
type: 'SET_FIRST_NAME' | |
}); | |
const setLastName = lastName => ({ | |
lastName, | |
type: 'SET_LAST_NAME' | |
}); | |
const incrementRequests = () => ({ | |
type: 'INCREMENT_REQUEST' | |
}); | |
// DECORATORS | |
// a function that receives a class or another function | |
// and returns an enhanced version of the original input. | |
const withSetState = Base => class extends Base { | |
setState(arg) { | |
this.state = { | |
...this.state, | |
...(isFunction(arg) ? arg(this.state) : arg), | |
}; | |
} | |
}; | |
class extends withSetState(HTMLElement) {} | |
// in the future we will be able to: | |
@withSetState | |
class extends HTMLElement {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment