JS Summit: Modular React & Redux

JS Summit: Modular React & Redux

94bd558238b69c45d3d3e15797ae94f7?s=128

Jeremy Fairbank

February 25, 2016
Tweet

Transcript

  1. 5.

    Modularity • Independent • Single Responsibility • Small • Testable

    • Apply to React components • Apply to Redux state and reducers
  2. 6.
  3. 7.
  4. 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> ); } } <NameTag name="Jeremy Fairbank"/>
  5. 10.

    <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> );
  6. 12.

    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
  7. 13.

    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?
  8. 14.

    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> ); } }
  9. 15.

    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> ); } }
  10. 16.

    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
  11. 17.

    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
  12. 19.

    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 }); } }
  13. 20.

    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.)
  14. 21.
  15. 24.

    { name: 'Jet', type: 'UPDATE_NAME' } Action Provider & connect

    { user: { name: 'Jeremy', email: 'jeremy@example.com', username: 'elpapapollo' } } Store App Dispatch
  16. 25.

    { name: 'Jet', type: 'UPDATE_NAME' } Action Provider & connect

    { user: { name: 'Jet', email: 'jeremy@example.com', username: 'elpapapollo' } } New Store State App Dispatch { user: { name: 'Jeremy', email: 'jeremy@example.com', username: 'elpapapollo' } } Store Reducer