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

Props Vs State

Props Vs State

The Tao of the React Component

Eric Eldredge

November 19, 2014
Tweet

More Decks by Eric Eldredge

Other Decks in Programming

Transcript

  1. What is a React Component? • Basically, a function that

    transforms data into HTML. • The same data always renders the same HTML. * By data, we mean props and state. * By HTML, we mean a Virtual DOM node.
  2. MyComponent = React.createClass({ contextTypes: { previousURL: React.PropTypes.string }, propTypes: {

    expanded: React.PropTypes.bool }, getDefaultProps: function() { return {expanded: false}; }, componentWillReceiveProps: function(props) { if(props.expanded) this.setState({url: this.context.previousURL}); }, shouldComponentUpdate: function(nextProps, nextState) { return nextProps.expanded !== this.props.expanded; }, render: function() { return ( <a href="{this.state.url}" data-expanded={this.props.expanded ? '' : null} > A link </a> ); } });
  3. What is a React Component? • A React Component is

    also a state machine • Update a component’s state by calling setState() • Or by calling setProps() (on the top component only)
  4. What are props? • Arguments to the Component render function

    • Props come from outside the Component
  5. var Tab = React.createClass({ render: function() { return ( <div

    className='Tab' onClick={this.props.onClick} data-active={this.props.active ? '' : null} > {this.props.children} </div> ); } }); var active = false; (function renderTab() { React.render( <Tab active={active} onClick={renderTab}> Hello, World! </Tab>, document.body ); active = !active; }());
  6. What is State? • Also used in the Component render

    function • State is isolated inside the Component • State persists between renders
  7. var Tab = React.createClass({ getInitialState: function() { return {active: false};

    }, handleClick: function() { this.setState({active: !this.state.active}); }, render: function() { return ( <div className='Tab' onClick={this.handleClick} data-active={this.state.active ? '' : null} > {this.props.children} </div> ); } }); (function renderTab() { React.render(<Tab>Hello, World!</Tab>, document.body); }());
  8. Interactive Props • Some components are affected by user interactions

    • Since props are immutable, interactions that change the component must either be handled by the parent component, or translated to state
  9. React Form Components React.createClass({ getInitialState: function() { return {value: 'Hello!'};

    }, handleChange: function(event) { this.setState({value: event.target.value}); }, render: function() { return ( <form> <input type="text" onChange={this.handleChange} /> <input type="text" value={this.state.value}/> </form> ); } });
  10. var Tab = React.createClass({ render: function() { return ( <div

    className='Tab' onClick={this.props.onClick} data-active={this.props.active ? '' : null} > {this.props.children} </div> ); } }); var active = false; (function renderTab() { React.render( <Tab active={active} onClick={renderTab}> Hello, World! </Tab>, document.body ); active = !active; }());
  11. Uncontrolled Components • Values maintained in state • parent components

    might pass in callbacks to be notified of changes
  12. var Tab = React.createClass({ getInitialState: function() { return {active: false};

    }, handleClick: function() { this.setState({active: !this.state.active}); }, render: function() { return ( <div className='Tab' onClick={this.handleClick} data-active={this.state.active ? '' : null} > {this.props.children} </div> ); } }); (function renderTab() { React.render(<Tab>Hello, World!</Tab>, document.body); }());
  13. The best of both worlds: Controllables • An interactive component

    needs to maintain its own state • But sometimes it needs to yield control • Like React’s Form Components with interactive props • github.com/matthewwithanm/react-controllables
  14. var Tab = React.createClass({ mixins: [ControllablesMixin], controllables: ['active'], getDefaultProps: function()

    {return {defaultActive: false};}, handleClick: function(event) { if (this.props.onClick) this.props.onClick(event); this.setState({active: !this.state.active}); }, render: function() { return ( <div className='Tab' data-active={this.getControllableValue('active') ? '' : null} onClick={this.handleClick} > {this.props.children} </div> ); } }); (function renderTabs(active) { React.render(<div> <Tab onActiveChange={renderTabs}>Hello, World!</Tab>, <Tab active={active}>Goodbye, World!</Tab>, </div>, document.body); }());
  15. Finally, a word about PropTypes • Props are your Component

    API • Validate usage of your Component • Document usage of your Component
  16. var Tab = React.createClass({ displayName: 'Tab', propTypes: { active: React.PropTypes.bool,

    onClick: React.PropTypes.func }, render: function() { return ( <div className='Tab' onClick={this.props.onClick} data-active={this.props.active ? '' : null} > {this.props.children} </div> ); } });
  17. More words about PropTypes • React provides the most common

    PropTypes under React.PropTypes • Custom PropTypes are possible, but sometimes it’s a bit tricky to fully emulate what the builtin types do • github.com/gcanti/tcomb-validation • flowtype.org