Upgrade to Pro — share decks privately, control downloads, hide ads and more …

State Management with MobX

State Management with MobX

React Bangkok 3.0.0

More Decks by Manatsawin Hanmongkolchai

Other Decks in Programming

Transcript

  1. About Me • Manatsawin Hanmongkolchai • Junior Architect @ Wongnai

    ◦ We do everything from infrastructure to frontend
  2. Redux works, but... • It is quite boilerplatey ◦ Some

    people just give up and just use it as key value store • It has too many friends ◦ react-redux, immutablejs, redux-immutable, redux-thunk/saga ◦ Some people add reselect, redux-action • It is hard to get new people onboard ◦ Not only they have to learn React and Redux, they have to learn ALL of the above as well
  3. Redux works, but... • It has one store ◦ 75%

    of wongnai.com page content is Redux state. Why we have to send you empty delivery coupons store when you'll never look at it? ◦ We're working on it. Stay tuned on life.wongnai.com
  4. $scope.data = []; let scope = observable({ data: [] });

    $http.get('/_api/restaurants.json') .then(function(response){ $scope.data = response.data; }); fetch('/_api/restaurants.json') .then((res) => res.json()) .then(action((data) => { scope.data = data; })); AngularJS MobX
  5. $scope.data = []; let scope = observable({ data: [] });

    $http.get('/_api/restaurants.json') .then(function(response){ $scope.data = response.data; }); fetch('/_api/restaurants.json') .then((res) => res.json()) .then(action((data) => { scope.data = data; })); AngularJS MobX Put this where you used to put $scope.$apply
  6. <ul> <li ng-repeat="item in data" ng-bind="item.name"></li> </ul> observer((props) => {

    return <ul>{state.data.map((item, index) => ( <li key={index}>{item.name}</li> ))}</ul>; }); AngularJS MobX
  7. <ul> <li ng-repeat="item in data" ng-bind="item.name"></li> </ul> observer((props) => {

    return <ul>{state.data.map((item, index) => ( <li key={index}>{item.name}</li> ))}</ul>; }); AngularJS MobX Wrap your view with this HOC
  8. … is mostly the same as higher order function observer(function(props){

    return <ul>{state.data.map((item, index) => ( <li key={index}>{item.name}</li> ))}</ul>; })
  9. @observer function(props){ return <ul>{state.data.map((item, index) => ( <li key={index}>{item.name}</li> ))}</ul>;

    } Only update when state.data is updated Not when state.otherField is updated
  10. let Item = observer((props) => <li>{props.item.name}</li>); let View = observer(()

    => ( <ul>{state.data.map((item, index) => ( <Item key={index} item={item} /> ))}</ul> ));
  11. let Item = observer((props) => <li>{props.item.name}</li>); let View = observer(()

    => ( <ul>{state.data.map((item, index) => ( <Item key={index} item={item} /> ))}</ul> )); Dereference things as late as possible <Item key={index} name={item.name} />
  12. let Item = observer((props) => <li>{props.item.name}</li>); let View = observer(()

    => ( <ul>{state.data.map((item, index) => ( <Item key={index} item={item} /> ))}</ul> )); Let MobX know that this component depends on item.name
  13. export default class Settings { @observable settings = { color1:

    '#82cef7', }; @observable saving = false; @observable error = null; @observable url = null; }
  14. export default class Settings { @observable settings = { color1:

    '#82cef7', }; @observable saving = false; @observable error = null; @observable url = null; } Just plain old OOP
  15. export default class Settings { async save(url){ let result =

    await this._post(url, { data: JSON.stringify(this.settings), }); runInAction('set url', () => { this.url = result.url; }); } }
  16. import BaseSettings from './base'; export default class AlertStore extends BaseSettings

    { @observable settings = { color1: '#82cef7', color2: '#ffffff', color3: '#ffffff', } // free save!! }