Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save octaviogb/5884f004fe9d6b6f86171dd54e693df0 to your computer and use it in GitHub Desktop.
Save octaviogb/5884f004fe9d6b6f86171dd54e693df0 to your computer and use it in GitHub Desktop.
presentation about global state and 3 UI solutions

STATEFUL COMPONENT

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: 0 };
  }
  incrementValue() {
    this.setState({
      value: this.state.value + 1
    });
  }
  render() {
    const increment = this.incrementValue.bind(this);
    return (<main>
      <h1>{this.state.value}</h1>
      <button 
        onClick={increment}
      >+1
      </button>
    </main>)
  }
}

JSBin


DUMB COMPONENT

class Incrementer extends React.Component {
  render() {
    return (<main>
      <h1>{this.props.value}</h1>
      <button 
        onClick={this.props.incrementValue}
      >+1
      </button>
    </main>);
  }
}

SMART COMPONENT

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    }
  }
  incrementValue() {
    this.setState({
      value: this.state.value + 1
    });
  }
  render() {
    const increment = this.incrementValue.bind(this);
    return (<Incrementer 
              value={this.state.value}
              incrementValue={increment}
              />)
  }
}

JSBin


STATELESS COMPONENT

// state container
const state = {value: 0}

// actions
const incrementState = (dispatch, state) => 
	() => dispatch({value: state.value + 1});
  
// dumb component
const Incrementer = connect((props) => <main>
        <h1>{props.value}</h1>
        <button 
          onClick={props.actions.incrementState}
        >
          +1
        </button>
      </main>, state, {incrementState});   
    
/* RENDER */
ReactDOM.render(<Incrementer/>, 
		document.querySelector("div"))

STATE CONNECTOR

const connect = (el, state, actions) => 
 class Connect extends React.Component {
  constructor() {
    super();
    this.state = state;
  }
  render() {
    const { state, setState } = this;
    const dispatch = setState.bind(this);
    const binderReducer = (current, next) => 
    	({...current, 
         [next]: actions[next](dispatch, state)});
    const bindedActions = Object.keys(actions)
    				.reduce(binderReducer, {});
    const props = {...state, actions: bindedActions};
    return React.cloneElement(el(props));
  }
 }

JSBin


CLOJURESCRIPT + Reagent

(ns cljsfiddle.app
  (:require [reagent.core :refer [atom]]])
  
;; state container
(def state (atom {:value 0}))

;; action
(defn increment-state [state] 
  (fn [_] 
    (swap! state update-in [:value] inc)))

;; dumb component
(defn incrementer [] [:main 
                      [:h1 (:value @state)] 
                      [:button 
                        {:on-click (increment-state state)} 
                        "+1"]])
;; render
[incrementer]

CLJS fiddle


TypeScrypt + Angular

@Injectable()
export class AppService {
  value = 0;
  incrementState = () => Promise.resolve(this.value++);
}
@Component({
  selector: 'body',
  template: `
    <h1>{{value}}</h1>
    <button (click)="incrementState()">+1</button>
  `,
  providers: [AppService]
})
export class AppComponent implements OnInit{
  constructor(private appService: AppService) { }
  value = 0;
  incrementState = () => this.appService.incrementState()
  .then(value => this.value = value);
}
bootstrap(AppComponent);

Punker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment