Skip to content

Instantly share code, notes, and snippets.

@leofavre
Last active October 10, 2018 19:22
Show Gist options
  • Save leofavre/e6c2fcef14e20755da84f9524649c84c to your computer and use it in GitHub Desktop.
Save leofavre/e6c2fcef14e20755da84f9524649c84c to your computer and use it in GitHub Desktop.
Front-End concepts from React and Redux applied to web components
// 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