Forget What You Know

Forget What You Know

Just React things...

061e3bae4ce4234a2194d20a382e5d19?s=128

Christopher Pitt

September 22, 2016
Tweet

Transcript

  1. FORGET WHAT YOU KNOW

  2. WHAT I LEARNED ABOUT REACT THOUGH I MOSTLY DO SERVER-SIDE

    AND A LITTLE BIT OF "WELL THAT WORKS WELL ENOUGH" JAVASCRIPT
  3. None
  4. const $issues = $(".issues") $.ajax({ "url": "https://api.github.com/repos/facebook/react/issues", "success": function(issues) {

    issues.forEach(function(issue) { $issues.append(` <li class="issue"> <a class="title">${issue.title}</a> <div class="extract">${issue.body}</div> </li> `) }) } })
  5. $issues.on("click", ".title", function(e) { const $title = $(this) $title.parent(".issue").toggleClass("highlight") $title.siblings(".extract").toggle()

    })
  6. None
  7. "success": function(issues) { issues.forEach(function(issue) { $issues.append(` <li class="issue"> <a class="title">${issue.title}</a>

    <a class="hide" data-id="${issue.id}">hide</a> <div class="extract">${issue.body}</div> </li> `) }) }
  8. let hidden = [] $issues.on("click", ".hide", function(e) { const $hide

    = $(this) const id = $hide.data("id") hidden.includes(id) || hidden.push(id) });
  9. $.ajax({ "url": "https://api.github.com/repos/facebook/react/issues", "success": function(issues) { issues.forEach(function(issue) { $issues.append(`...`) })

    } })
  10. const render = function(issues) { $issues.empty() issues .filter(function(issue) { return

    ! hidden.includes(issue.id) }) .forEach(function(issue) { $issues.append(`...`) }) }
  11. const fetch = function() { $.ajax({ "url": "https://api.github.com/repos/facebook/react/issues", "success": render

    }) } fetch()
  12. let hidden = [] try { hidden = JSON.parse(localStorage["hidden"]) }

    catch (e) { console.warn("could not load hidden ids from local storage") }
  13. $issues.on("click", ".hide", function(e) { const $hide = $(this) const id

    = $hide.data("id") hidden.includes(id) || hidden.push(id) localStorage["hidden"] = JSON.stringify(hidden) fetch() });
  14. OTHER THINGS WE COULD IMPROVE...

  15. IMPERATIVE CODE ▸ make ajax request ▸ render list of

    items ▸ do a thing on click ▸ persist ui state for refresh
  16. IMPERATIVE CODE this is how to make things look like

    I want
  17. DECLARATIVE CODE this is what I want things to look

    like given any state
  18. <ul class="issues"> <li class="issue" ng-repeat="issue in issues" ng-if="visible"> <a class="title">{{

    issue.title }}</a> <a class="hide" data-id="{{ issue.id }}">hide</a> <div class="extract">{{ issue.body }}</div> </li> </ul>
  19. const Issues = ({ issues }) => { return (

    <ul className="issues"> {issues.forEach((issue, key) => { if (!issue.visible) { return } return <Issue {...issue} key={key} /> }) </ul> ) }
  20. class Issues extends React.Component { render() { return ( <ul

    className="issues"> {this.props.issues.forEach((issue, key) => { if (!issue.visible) { return } return <Issue {...issue} key={key} /> }) </ul> ) } }
  21. WHY IS DECLARATIVE CODE SOMETIMES BETTER?

  22. REACT IS SCARY

  23. USE FUNCTIONS INSTEAD OF CLASSES WHERE POSSIBLE

  24. class Issues extends React.Component { componentWillMount() { // do something

    before the component mounts } componentWillReceiveProps() { // do something after the component mounts } shouldComponentUpdate() { // return false if the component shouldn't re-render } }
  25. class Issues extends React.Component { constructor(...params) { super(...params) this.state =

    { "text": "...list issues", } } async componentDidMount() { const response = await fetch("http://codepen.io/assertchris/pen/rrjKPN.css") const text = await response.text() this.setState({ ...this.state, "length": text.length, }) } render() { if (this.state.length) { return <span>{ this.state.text } ! { this.state.length }</span> } return <span>{ this.state.text }</span> } }
  26. USE IMMUTABLE DATA WHERE POSSIBLE

  27. this.setState({ ...this.state, "length": text.length, }) return [ ...items, "new item",

    ]
  28. let state1 = Immutable.Map({ "text": "...list items", "length": 0, })

    let state2 = map1.set("length", 43) state1.get("length") // 0 state2.get("length") // 43 state1.equals(state2) // false
  29. https://facebook.github.io/immutable-js

  30. YOU DON'T ALWAYS NEED FLUX OR REDUX OR REFLUX...

  31. https://medium.com/@dan_abramov/ you-might-not-need-redux-be46360cf367

  32. USE SERVICE LOCATION FOR PLUGIN ARCHITECTURE

  33. // ...the code you write ! import { Ioc }

    from "adonis-fold" import { hiddenReducer, highlightedReducer } from "path/to/core" Ioc.bind("reducers", function() { return [ hiddenReducer, highlightedReducer, ] })
  34. // ...the code others write ! import { Ioc }

    from "adonis-fold" import { pluginReducer } from "path/to/plugin" const previous = Ioc.use("reducers") Ioc.bind("reducers", function() { return [ ...previous, pluginReducer, ] })
  35. const Issues = (props) => { const globals = Ioc.use("global-issues")

    if (globals.length) { return ( <ul className="Issues"> { renderGlobalIssues(globals) } { renderIssues(props.issues) } </ul> ) } return ( <ul className="Issues"> { renderIssues(props.issues) } </ul> ) }
  36. http://adonisjs.com/docs/3.0/overview#ioc-container

  37. https://www.amazon.com/dp/B01BSTEDJ0

  38. Thanks https://speakerdeck.com/chrispitt/forget-what-you-know @assertchris