Skip to content

Instantly share code, notes, and snippets.

@ericelliott
Last active December 26, 2022 07:05
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save ericelliott/7e05747b891673eb704b to your computer and use it in GitHub Desktop.
Save ericelliott/7e05747b891673eb704b to your computer and use it in GitHub Desktop.
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
Copy link
Author

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
Copy link

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

@zebulonj
Copy link

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