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

JS Summit: Modular React & Redux

JS Summit: Modular React & Redux

Jeremy Fairbank

February 25, 2016
Tweet

More Decks by Jeremy Fairbank

Other Decks in Programming

Transcript

  1. Modularity • Independent • Single Responsibility • Small • Testable

    • Apply to React components • Apply to Redux state and reducers
  2. class NameTag extends React.Component { componentWillMount() { this.setState({ name: this.props.name

    }); } updateName(name) { this.setState({ name }); } render() { return ( <div> <p>Hello, my name is {this.state.name}</p> <p> <input type="text" value={this.state.name} onChange={e => this.updateName(e.target.value)} /> </p> </div> ); } } <NameTag name="Jeremy Fairbank"/>
  3. <NameTag name="Jeremy Fairbank" onChange={myUpdateFunction}/> const NameTag = ({ name, onChange

    }) => ( <div> <p> Hello, my name is {name} </p> <p> <input type="text" value={name} onChange={e => onChange(e.target.value)} /> </p> </div> );
  4. const NameTag = ({ name, onChange }) => ( <div>

    <p> Hello, my name is {name} </p> <p> <input type="text" value={name} onChange={e => onChange(e.target.value)} /> </p> </div> ); External state
  5. const NameTag = ({ name, onChange }) => ( <div>

    <p> Hello, my name is {name} </p> <p> <input type="text" value={name} onChange={e => onChange(e.target.value)} /> </p> </div> ); Who manages the state?
  6. class NameTag extends React.Component { componentWillMount() { this.setState({ name: this.props.name

    }); } updateName(name) { this.setState({ name }); } render() { return ( <div> <p>Hello, my name is {this.state.name}</p> <p> <input type="text" value={this.state.name} onChange={e => this.updateName(e.target.value)} /> </p> </div> ); } }
  7. class NameTag extends React.Component { componentWillMount() { this.setState({ name: this.props.name

    }); } updateName(name) { this.setState({ name }); } render() { return ( <div> <p>Hello, my name is {this.state.name}</p> <p> <input type="text" value={this.state.name} onChange={e => this.updateName(e.target.value)} /> </p> </div> ); } }
  8. class NameTag extends React.Component { componentWillMount() { this.setState({ name: this.props.name

    }); } updateName(name) { this.setState({ name }); } render() { return ( <div> <p>Hello, my name is {this.state.name}</p> <p> <input type="text" value={this.state.name} onChange={e => this.updateName(e.target.value)} /> </p> </div> ); } } Many components => State strewn across app
  9. class NameTag extends React.Component { componentWillMount() { this.setState({ name: this.props.name

    }); } updateName(name) { this.setState({ name }); } render() { return ( <div> <p>Hello, my name is {this.state.name}</p> <p> <input type="text" value={this.state.name} onChange={e => this.updateName(e.target.value)} /> </p> </div> ); } } Intermingling view and behavior => Violating SRP
  10. const App = ({ name, onChangeName }) => ( <AppDashboard

    name={name} onChangeName={onChangeName}/> ); const AppDashboard = ({ name, onChangeName }) => ( <Dashboard> <Panel> <User name={name} onChangeName={onChangeName}/> </Panel> </Dashboard> ); const User = ({ name, onChangeName }) => ( <NameTag name={name} onChange={onChangeName}/> ); { name: 'Jeremy', onChangeName: (name) => { updateSomeGlobalState({ name }); } }
  11. Wishlist • Manage state in one place outside of components

    in a modular fashion. • Define behavior separate from view. • Inject props without deep passing. (Like partial application.)
  12. { name: 'Jet', type: 'UPDATE_NAME' } Action Provider & connect

    { user: { name: 'Jeremy', email: '[email protected]', username: 'elpapapollo' } } Store App Dispatch
  13. { name: 'Jet', type: 'UPDATE_NAME' } Action Provider & connect

    { user: { name: 'Jet', email: '[email protected]', username: 'elpapapollo' } } New Store State App Dispatch { user: { name: 'Jeremy', email: '[email protected]', username: 'elpapapollo' } } Store Reducer