Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
React - Complete Reusable Component

React Reusable Component Factory

'use strict';

const ENTER_KEY = 13;

const emailFactory = function ({
  React,
  setEmail,
  setEditMode
} = {}) {

  const EmailField = function (props) {
    return {
      propTypes: {
        email: React.PropTypes.string,
        isEditMode: React.PropTypes.bool
      },

      props,

      onKeyUp (e) {
        if (e.keyCode !== ENTER_KEY) return;
        setEmail(e.target.value);
      },

      render () {
        const isEditMode = this.props.isEditMode;
        const email = this.props.email;

        const displayStyle = {
          display: isEditMode ? 'none' : 'block'
        };
        const editStyle = {
          display: isEditMode ? 'block' : 'none'
        };

        return (
          <div>
            <p
              onClick={ () => setEditMode(true) }
              style = { displayStyle }
              >{ email }
            </p>
            <input
              type="email"
              onKeyUp={ this.onKeyUp }
              style = { editStyle }
              placeholder = { email } />
          </div>
        );
      }
    };
  };

  return EmailField;

};

export default emailFactory;
@ericelliott

This comment has been minimized.

Copy link
Owner Author

@ericelliott ericelliott commented May 20, 2015

React Reusable Component Standalone

On the suggestion of @gaearon, this implementation drops the factory in favor of passing actions in with props. This has the advantage of allowing you to validate your actions with propTypes:

'use strict';

import React from 'react';
import assign from 'lodash/object/assign';

const { PropTypes } = React;
const ENTER_KEY = 13;
const requiredFunction = PropTypes.func.isRequired;

const propTypes = {
  propTypes: {
    email: PropTypes.string,
    isEditMode: PropTypes.bool,
    actions: PropTypes.shape({
      setEmail: requiredFunction,
      setEditMode: requiredFunction
    })
  }
};

let EmailField = function (props) {
  return {
    props,

    render () {
      const { setEmail, setEditMode } = this.props.actions;

      const isEditMode = this.props.isEditMode;
      const email = this.props.email;

      const displayStyle = {
        display: isEditMode ? 'none' : 'block'
      };
      const editStyle = {
        display: isEditMode ? 'block' : 'none'
      };

      return (
        <div>
          <p
            onClick={ () => setEditMode(true) }
            style = { displayStyle }
            >{ email }
          </p>
          <input
            type="email"
            onKeyUp={ function onKeyUp (e) {
              if (e.keyCode !== ENTER_KEY) return;
              setEmail(e.target.value);
            } }
            style = { editStyle }
            placeholder = { email } />
        </div>
      );
    }
  };
};

export default assign(EmailField, propTypes);
@caiovaccaro

This comment has been minimized.

Copy link

@caiovaccaro caiovaccaro commented May 22, 2015

@ericelliott what "setEmail"and "setEditMode" would look like?

@zebulonj

This comment has been minimized.

Copy link

@zebulonj zebulonj commented Jun 3, 2015

@ericelliott I assume your intention is to use prototypal inheritance to inherit from React.Component (I've seen you make references to this elsewhere). Where does this actually happen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.