2017-05-18 5 views
0

Ich habe dieses HOC erstellt, das ein Benutzer in zwei Komponenten übergeben kann, und es gibt eine Schriftart tolle Stack-Symbole zurück.Reagieren auf Komponenten höherer Ordnung

const StackIcons = (BaseIcon, TopIcon) => (props) => { 
    const { container, base, top } = props; 
    return (
    <span className={`fa-stack fa-lg fa-${container}`}> 
     <BaseIcon stack="2x" className="info" {...base} /> 
     <TopIcon stack="1x" isInverse={true} {...top} /> 
    </span> 
    ); 
}; 

Ich brauche die verschiedene Requisiten zwischen dem Behälter, Basis-Symbol, und Top-Symbol zu unterscheiden, so habe ich beschlossen, ein Objekt zu übergeben, die eine Eigenschaft für Container (string) hat, Basis (Objekt) und oben (Objekt).

Zum Beispiel

const object = { 
    container: 'lg', 
    base: { 
    stack: '2x', 
    className: 'info' 
    }, 
    top: { 
    stack: '1x', 
    isInverse: true 
    } 
} 

Mein größtes Problem mit diesem Ansatz ist die Tatsache, die propTypes und defaultProps nicht funktionieren.

// StackIcons.defaultProps = { 
//  base: { 
//   stack: '2x', 
//   className: 'info' 
//  }, 
//  top: { 
//   stack: '1x', 
//   isInverse: true 
//  }, 
//  container: 'lg' 
// }; 

StackIcons.propTypes = { 
    base: PropTypes.object.isRequired, 
    top: PropTypes.object.isRequired, 
    container: PropTypes.oneOf(['lg', '2x', '3x', '4x', '5x']).isRequired, 
}; 

Da die defaultProps nicht arbeiten, habe ich beschlossen, sie aus und hartcodiert die Requisiten für Grund- und Deck Symbol Komponenten kommentiert, aber dann kann der Verbraucher die Standards Requisiten außer Kraft setzen, indem sie in den entsprechenden Requisiten vorbei.

Nutzung:

const StackedIcons = StackIcons(<CircleIcon />, <DollarSign />); 

// in render method 
<StackedIcons /> // use default props 

// or override the defaultProps. 
<StackedIcons container="..." base={{...}} top={{...}} /> 
  1. Wie die propTypes und defaultTypes zu beheben?
  2. Gibt es einen besseren Weg?

Ich habe so etwas wie dies versucht:

const StackIcons = (BaseIcon) => (baseIconProps) => (TopIcon) => (topIconProps) => {...} 

Aber ich war kein Fan, dies zu tun:

const StackedIcons = StackIcons(<CircleIcon />)({ stack: '12x', className: 'info' })(<DollarSign />) 

// in render method 
<StackedIcons stack="1x" isInverse={true} /> 

Vielen Dank an Yury Tarabanko

! Hier ist meine aktualisierte Arbeitsversion:

import React from 'react'; 
import PropTypes from 'prop-types'; 

const stackIcons = (BaseIcon, TopIcon) => { 

    const StackIcons = (props) => { 
     const {container, base, top} = props; 
     return (
      <span className={`fa-stack fa-lg fa-${container}`}> 
       <BaseIcon {...base} /> 
       <TopIcon {...top} /> 
      </span> 
     ); 
    }; 

    StackIcons.defaultProps = { 
     base: { 
      stack: '2x', 
      className: 'info' 
     }, 
     top: { 
      stack: '1x', 
      isInverse: true 
     }, 
     container: 'lg' 
    }; 

    StackIcons.propTypes = { 
     base: PropTypes.object.isRequired, 
     top: PropTypes.object.isRequired, 
     container: PropTypes.oneOf(['lg', '2x', '3x', '4x', '5x']).isRequired, 
    }; 

    return StackIcons; 
}; 

export default stackIcons; 
+0

sein was nicht mit 'defaultProps arbeiten'? –

+0

Wenn ich die defaultProps auskommentiere und Stack-, className- und isInverse-Requisiten sowohl für das Basis- als auch für das obere Symbol loslasse, funktioniert der Stil für fontawesome nicht. Außerdem, wenn die propTypes alle benötigt werden, und noch einmal, werde ich die Stapel-, className- und isInverse-Requisiten sowohl für das Basis- als auch für das obere Symbol los und gebe dann nichts als Requisiten weiter, das isRequired funktioniert gar nicht. – FNMT8L9IN82

Antwort

1

Sie können nicht propTypes auf StackIcons gesetzt, weil es nicht eine Komponente ist. Es gibt eine Komponente zurück. Sie müssen propTypes auf zurückgegebene Komponente festlegen.

const StackIcons = (BaseIcon, TopIcon) => { 

    const Wrapped = props => ... 

    Wrapped.propTypes = {} 

    Wrapped.defaultProps = {} 

    return Wrapped 
}; 

Verwendung sollte

// here StackIcons is HOC 
// you can't use it like <StackIcons/> 
// but StackedIcons is just a stateless component 
const StackedIcons = StackIcons(CircleIcon, DollarSign); 

// so you can use it like this 
<StackedIcons /> // use default props 

// or override the defaultProps. 
<StackedIcons container="..." base={{...}} top={{...}} /> 
+0

Was meinst du damit, es ist keine Komponente, aber es gibt eine Komponente zurück? – FNMT8L9IN82

+0

Was könnte das anders als diese Funktion bedeuten, ist keine Komponente? Es ist eine Komponente höherer Ordnung, die ** eine Komponente ** zurückgibt, für die Sie Requisitenarten und ähnliches angeben möchten. –

+0

Ok, ich verstehe es! Danke – FNMT8L9IN82

Verwandte Themen