Ready for Async Rendering

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=47 koba04
April 19, 2018

Ready for Async Rendering

45daf58c77e9dbbab5a1c8a5afc7ac5c?s=128

koba04

April 19, 2018
Tweet

Transcript

  1. 3FBEZGPS"TZOD3FOEFSJOH 4DSBNCMF   !LPCB

  2. None
  3. "HFOEB w 8IBUJT"TZOD3FOEFSJOH  w -JGFDZDMF.FUIPET4USJDU.PEF w 5JNF4MJDJOH w 3FBDU4VTQFOTF

    w "QQFOEJY v16.3 Changes
  4. 8IBUJT"TZOD3FOEFSJOH

  5. w 3FBDU'JCFSJTBOVOJUPGXPSL 㲈3FBDU&MFNFOU  w *UJTQPTTJCMFUPTUPQBOESFTVNFVQEBUFT 3FDBQ3FBDU'JCFS FiberA FiberB FiberD

    FiberE Commit all SideEffects Idle Time Idle Time Idle Time SideEffect SideEffect Host (DOM) FiberC Render Phase Commit Phase
  6. w 3FOEFS1IBTFʜ"TZOD w $PNNJU1IBTFʜ4ZOD 3FDBQ3FBDU'JCFS FiberA FiberB FiberD FiberE Commit

    all SideEffects Idle Time Idle Time Idle Time SideEffect SideEffect Host (DOM) FiberC Async Sync
  7. 4VTQFOEBOE3FTVNF FiberA FiberB FiberA FiberC Commit Low Priority Sync Priority

    Commit FiberA FiberB FiberC Low Priority Reuse Interrupt Suspend
  8. -JGFDZDMF.FUIPET

  9. $IBOHFTGPSMJGFDZDMFNFUIPET http://blog.koba04.com/post/2018/04/04/react-v163-changes/

  10. w $BMMFEBU3FOEFS1IBTF w 3FUVSOBQBSUJBMTUBUFCBTFEPOOFYU1SPQT w TUBUJDHFU%FSJWFE4UBUF'SPN1SPQT static getDerivedStateFromProps(nextProps, prevState) {

    if (nextProps.category !== prevState.category) { return { data: null, category: null }; } return null; } componentDidUpdate() { if (this.state.category == null) { fetchData(this.props.category).then((data) => { this.setState({category: this.props.category, data}); }); }
  11. w $BMMFEBU$PNNJU1IBTF w 3FUVSOBTOBQTIPU BOZ CFGPSFVQEBUFUIF)PTU w UIFTOBQTIPUJTQBTTFEUPDPNQPOFOU%JE6QEBUF HFU4OBQTIPU#FGPSF6QEBUF getSnapshotBeforeUpdate()

    { return { scrollHeight: document.body.scrollHeight, scrollTop: document.body.scrollTop, }; } componentDidUpdate(prevProps, prevState, snapshot) { const {body} = document; const {scrollTop, scrollHeight} = snapshot; body.scrollTop = scrollTop + (body.scrollHeight - scrollHeight); }
  12. https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples

  13. https://github.com/facebook/react/tree/master/packages/create-subscription

  14. 4USJDU.PEF

  15. w *EFOUJGZJOHDPNQPOFOUTVOTBGFMJGFDZDMFT w 8BSOJOHBCPVUMFHBDZTUSJOHSFG"1*VTBHF w %FUFDUJOHVOFYQFDUFETJEFF⒎FDUT 4USJDU.PEF const {StrictMode} =

    React; const App = () => ( <StrictMode> <Header /> <Main /> <Footer /> </StrictMode> );
  16. /FX$BQBCJMJUJFT

  17. https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html

  18. 5JNF4MJDJOH

  19. w #MPDLJOH6*UISFBEJTBOBXGVMFYQFSJFODF w 5IFSFBSFNBOZQFPQMFXIPVTFMPXQPXFSEFWJDFT w 8IZOPUEFCPVODFPSUISPUUMF 5IFBOTXFSJTʜ w SFRVFTU*EMF$BMMCBDL 5JNF4MJDJOH

    <AsyncMode> <FilterInput onChange={value => { ReactDOM.flushSync(() => this.setState({value})); this.setState({data: this.filterData(value)}); }} /> </AsyncMode>
  20. https://koba04.github.io/react-fiber-resources/examples/ Async Update Sync Update

  21. None
  22. https://zeit.co/blog/domains-search-web

  23. 3FBDU4VTQFOTF

  24. https://github.com/facebook/react/pull/12279

  25. w 3FBDU4VTQFOTFJTBGFBUVSFUPIBOEMFBTZODVQEBUFT w )5513FRVFTU w %ZOBNJD-PBEJOH w )BOEMJOHBTZODISPOPVTVQEBUFTBSFTPIBSEʜ w 4UBSU-PBEJOH

    "1*4VDDFTT &SSPSʜ w .BOZMPBEJOHTQJOOFST KBOLCZBGBTUSFTQPOTF 3FBDU4VTQFOTF
  26. 3FBDU4VTQFOTF "1*XJMMCFDIBOHFE import SimpleCacheProvider from ‘simple-cache-provider’; const cache = SimpleCacheProvider.createCache();

    const userFetcher = id => SimpleCacheProvider.createResource(id => fetch(`/api/users/${id}`).then(res => res.json()); )(cache, id); const User = props => { const user = userFetcher.read(props.id); return <div>{user.name}</div>; }; const Fallback = props => ( <React.Timeout ms={props.timeout}> {didExpire => didExpire ? props.placeholder : props.children} </React.Timeout> ); <Fallback placeholder=“Loading…” timeout={200}> <User id={100} /> </Fallback>
  27. 3FBDU4VTQFOTF "1*XJMMCFDIBOHFE import SimpleCacheProvider from ‘simple-cache-provider’; const cache = SimpleCacheProvider.createCache();

    const routeFetcher = Component => SimpleCacheProvider.createResource(Component => import(Component).then(module => module.default); )(cache, Component); const UserPage = () => { const Component = routeFetcher.read(‘./pages/User’); return <Component />; }; const Fallback = props => ( <React.Timeout ms={props.timeout}> {didExpire => didExpire ? props.placeholder : props.children} </React.Timeout> ); <Fallback placeholder=“Loading…” timeout={1000}> <UserPage /> </Fallback>
  28. Empty Pending Resolved Rejected read or preload throw promise return

    value from cache Cache load
  29. w 3FBDU4VTQFOTFJTCBTFEPO&SSPS#PVOEBSJFT UIPVHI XIJDIUISPXT1SPNJTFJOTUFBEPG&SSPS )PXEPFT3FBDU4VTQFOTFXPSL User Fallback Timeout throw Promise!

    (suspend) timeout render with fetched Data (resume)
  30. https://github.com/facebook/react/pull/12201

  31. w 5IF"1*JTOPUpOBM"1* NJHIUCFDIBOHFE w *IFBSESFOEFSGVODUJPONVTUOPUIBWFBOZTJEFF⒎FDUT  w 3FBDU4VTQFOTFPO443SFOEFSFS  w

    1SFSFOEFSBOEQSFMPBEJOHXJUIIJEEFOQSPQT w "XFTPNF8IFODBO*VTF3FBDU4VTQFOTF  w .BZCFJOʜ 3FBDU4VTQFOTF
  32. "QQFOEJY

  33. /FX$POUFYU"1* const LangContext = React.createContext(‘en’); const ThemeContext = React.createContext(‘dark’); const

    App = () => ( <LangContext.Provider value=“en”> <ThemeContext.Provider value=“dark”> <Child> <LangContext.Consumer>
 {lang => ( <ThemeContext.Consumer> {theme => ( <button className={theme}> {getMessage(‘click’, lang)} </button> )} </ThemeContext.Consumer> )} </LangContext.Consumer> </Child> </ThemeContext.Provider> </LangContext.Provider> );
  34. w )BSEUPUZQFDIFDLJOH w TIPVME$PNQPOFOU6QEBUFNJHIUCSFBLUIFVQEBUF 1SPCMFNTPGMFHBDZ$POUFYU"1* GrandChild Child Parent ThemeContext Brown

    -> Orange shouldComponentUpdate return false;
  35. w 0QUJNJ[FUIFVQEBUFTGPS$POUFYUWBMVF w 3FBDUVTFTCJUXJTFPQFSBUPSJUTJOUFSOBMT 0CTFSWFE#JUT VOTUBCMF⚠ const StoreContext = React.createContext(null,

    (prev, next) => { let changedBits = 0; if (prev.foo !== next.foo) changedBits |= 0b01; if (prev.bar !== next.bar) changedBits |= 0b10; return changedBits; }); // changedBits & unstable_observedBits !== 0 <StoreContext.Consumer unstable_observedBits={0b01}> {({foo}) => <div>{foo}</div> </StoreContext.Consumer> <StoreContext.Consumer unstable_observedBits={0b10}> {({bar}) => <div>{bar}</div> </StoreContext.Consumer>
  36. https://medium.com/@koba04/a-secret-parts-of-react-new-context-api-e9506a4578aa

  37. w 3FEVYBOE/FX$POUFYUBSFEJ⒎FSFOUMBZFST w SFBDUSFEVYNJHIUCFDIBOHFEXJUI/FX$POUFYU"1* w IUUQTHJUIVCDPNSFBDUKTSFBDUSFEVYQVMM w 8IZBSFZPVVTJOH3FEVY /FX$POUFYUBOE3FEVY

  38. 5IBOLT TQFBLFSEFDLDPNLPCB