redux-pluto

 redux-pluto

Folio Scramble! #1 で話した redux best practiceの話です。

D76231a2114896dfcc7b79ac69558b79?s=128

Yosuke Furukawa

April 19, 2018
Tweet

Transcript

  1. 8.

    ඇಉظσʔλϩʔυ • redux-async-loader import { compose } from 'recompose'; export

    default compose( // CSR Ͱ΋ SSR Ͱ΋྆ํಈ͘ // σʔλ͕ϩʔυ͞ΕͯΔͱloading state͕trueʹͳΓɺͦͷظؒ͸ // component͕render͞Εͳ͍ɻ asyncLoader((props, { dispatch }) => dispatch(loadUsers(props))), connect({ ... }, { ... }) )(class UserList exptends React.Component { // ... });
  2. 9.

    ඇಉظσʔλϩʔυ • ଞͷOSSࣄྫ • CyberAgent: https://github.com/kouhin/redux- dataloader • Next.js: getInitialProps

    https://github.com/zeit/ next.js/blob/master/examples/with-redux/pages/ index.js#L8-L13 • Nuxt.js: asyncData
  3. 13.

    reduxϑϩʔ੍ޚ • redux-effects-steps
 https://github.com/recruit-tech/redux-effects-steps • import { createAction } from

    'redux-actions'; import { steps } from 'redux-effects-steps'; import { fetchrRead } from 'redux-effects-fetchr'; const fetchUserRequest = createAction('FETCH_USER_REQUEST'); const fetchUserSuccess = createAction('FETCH_USER_SUCCESS'); const fetchUserFail = createAction('FETCH_USER_FAIL'); function fetchUser({ user }) { return steps(
 // ϦΫΤετͨ͠ΒϦΫΤετͨ͜͠ͱΛActionͰൃՐ͓ͤͯ͘͞ɻ fetchUserRequest(), // ຊϦΫΤετ fetch ॲཧ fetchrRead('users', { user }),
 // ੒ޭͨ͠ΒSuccess Action, ࣦഊͨ͠Β Failure Action [fetchUserSuccess, fetchUserFail] ); }
  4. 18.

    ducks • https://github.com/erikras/ducks-modular- redux /* @flow */ /** * Initial

    State */ const SALON = "redux-proto/salon"; export const [ FIND_SALON_BY_ID_REQUEST, FIND_SALON_BY_ID_SUCCESS, FIND_SALON_BY_ID_FAIL ] = createAsyncActionTypes(`${SALON}/find_id`); /** * Action creators */ const findSalonByIdRequest = createAction(FIND_SALON_BY_ID_REQUEST); const findSalonByIdSuccess = createAction(FIND_SALON_BY_ID_SUCCESS); const findSalonByIdFail = createAction(FIND_SALON_BY_ID_FAIL);
  5. 19.

    ducks • https://github.com/erikras/ducks-modular- redux /* @flow */ /** * Reducer

    */ export default (handleActions( { [FIND_SALON_BY_ID_REQUEST]: state => ({ … }), } )) /** * Selector */ export default (createSelector((state) => {…}, (items) => {…}))
  6. 20.

    ducks • actions, action creator, reducer ͚ͩͰ͸ͳ͘ɺselector· Ͱதʹ࣋ͭɻ • ϑΝΠϧ͕େ͖͘ͳΓͦ͏ͳ࣌͸ϑΥϧμʹͯ͠ϑΝΠϧ

    ෼ׂ͢Δͷ΋༗Γɻ͜ͷล͸޷͖ʹ • re-ducksͱ͍͏΋ͷ΋͋Δ͕ɺ͜ΕͱͷϋΠϒϦουײɻ • ཁ͸΍Γ͍ͨͷ͸Ϧιʔε࣠Ͱ·ͱΊΔํ͕ػೳ࣠Ͱ·ͱ ΊΔΑΓ΋ॻ͖΍͘͢ɺݟ΍͔ͬͨ͢ɻ
  7. 22.

    APIఆٛ • agreed https://github.com/recruit-tech/ agreed • Consumer Driven ContractΛ࣮ફ •

    ϑϩϯτΤϯυ͕த৺ʹͳͬͯ։ൃΛ͢͢Ί Δ࢓૊Έʹͳ͍ͬͯΔɻ
  8. 24.
  9. 33.

    Uncontrolled form // React ͩͱ͜͏ class NameForm extends React.Component {

    // … handleSubmit(event) { alert('A name was submitted: ' + this.input.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={(input) => this.input = input} /> </label> <input type="submit" value="Submit" /> </form> ); } }
  10. 34.

    Controlled form class NameForm extends React.Component { // … handleChange(event)

    { this.setState({value: event.target.value}); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this.handleCha </label> <input type="submit" value="Submit" /> </form> ); } }
  11. 35.

    Uncontrolled vs Controlled • Controlled ͳํ͸ ͜͜Ͱ͸ React ͷ state

    ͱ ͯ͠؅ཧ͢Δ • Uncontrolled ͳํ͸DOMʹ͚ͩ؅ཧͤ͞Δ
  12. 36.

    Uncontrolled vs Controlled • Facebook ͕ਪ঑ͯ͠Δͷ͸ Controlled Ұ୒ • React

    ͷ v-dom ߋ৽ͷλΠϛϯάͱ΋߹Θͤͯ React ͕࠷దԽͨ͠ํ๏ͰDOMʹ൓өͤ͞Δ͜ͱ ͕Ͱ͖Δ • ͪΐͬͱڽͬͨformΛ࡞Ε͹େମControlledͰ࣮ ૷͢Δඞཁ͕ग़ͯ͘Δɻ
  13. 37.

    Uncontrolled vs Controlled • jQuery UI Έ͍ͨͳϥΠϒϥϦ͸େମ Uncontrolled ͳํ๏Ͱ΍ͬͯΔ͜ͱ͕ଟ͍ʢؾ ͕͢Δʣ

    • طଘͷࢿ࢈͕jQueryʹ͋ͬͯͦΕ͕ Uncontrolled ͳํ๏Ͱ࣮ݱ͞ΕͯΔͳΒ࢖͏ͷ ΋ྑ͍͕ɺجຊ͸ Controlled Ͱྑ͍ؾ͕͢Δɻɹ
  14. 43.
  15. 49.
  16. 67.

    ·ͱΊ • ϕετϓϥΫςΟεʢΞʔΩςΫνϟฤʣ • ඇಉظϩʔυ • reduxϑϩʔ੍ޚ • ducks •

    APIఆٛ • ϕετϓϥΫςΟε(UIฤ) • ϑΥʔϜ • Ծ૝εΫϩʔϧ • ແݶεΫϩʔϧ • όουϓϥΫςΟε • babel plugin…, onlyUpdateForPropTypes…, etc