मैं सशर्त रूप से एक प्रतिक्रिया घटक कैसे लपेटता हूं?


86

मेरे पास एक घटक है जिसे कभी-कभी <anchor>ए और दूसरे के रूप में प्रदान किया जाना चाहिए <div>। यह propनिर्धारित करने के लिए मैंने पढ़ा है, है this.props.url

यदि यह मौजूद है, तो मुझे एक में लिपटे घटक को प्रस्तुत करना होगा <a href={this.props.url}>। अन्यथा यह सिर्फ एक के रूप में प्रदान किया जाता है <div/>

मुमकिन?

यह वही है जो मैं अभी कर रहा हूं, लेकिन लगता है कि इसे सरल बनाया जा सकता है:

if (this.props.link) {
    return (
        <a href={this.props.link}>
            <i>
                {this.props.count}
            </i>
        </a>
    );
}

return (
    <i className={styles.Icon}>
        {this.props.count}
    </i>
);

अपडेट करें:

यहाँ अंतिम लॉकअप है। टिप के लिए धन्यवाद, @ सुल्तान !

import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';

export default class CommentCount extends Component {

    static propTypes = {
        count: PropTypes.number.isRequired,
        link: PropTypes.string,
        className: PropTypes.string
    }

    render() {
        const styles = require('./CommentCount.css');
        const {link, className, count} = this.props;

        const iconClasses = classNames({
            [styles.Icon]: true,
            [className]: !link && className
        });

        const Icon = (
            <i className={iconClasses}>
                {count}
            </i>
        );

        if (link) {
            const baseClasses = classNames({
                [styles.Base]: true,
                [className]: className
            });

            return (
                <a href={link} className={baseClasses}>
                    {Icon}
                </a>
            );
        }

        return Icon;
    }
}

आप const baseClasses =उस if (this.props.link)शाखा में भी जा सकते हैं । जैसा कि आप ES6 का उपयोग कर रहे हैं, इसलिए आप स्थानीय चर के रूप में const {link, className} = this.props;उपयोग करके linkऔर फिर थोड़ा सरल भी कर सकते हैं className
सुल्तान

यार, मैं इसे प्यार करता हूँ। ईएस 6 के बारे में अधिक से अधिक सीखना और यह हमेशा पठनीयता में सुधार करता है। अतिरिक्त टिप के लिए धन्यवाद!
ब्रैंडन डरहम

1
"अंतिम लॉकअप" क्या है?
क्रिस हैरिसन

जवाबों:


93

बस एक चर का उपयोग करें।

var component = (
    <i className={styles.Icon}>
       {this.props.count}
    </i>
);

if (this.props.link) {
    return (
        <a href={this.props.link} className={baseClasses}>
            {component}
        </a>
    );
}

return component;

या, आप सामग्री को प्रस्तुत करने के लिए एक सहायक फ़ंक्शन का उपयोग कर सकते हैं। JSX किसी अन्य की तरह कोड है। यदि आप दोहराव कम करना चाहते हैं, तो फ़ंक्शन और चर का उपयोग करें।


22

अपने तत्व को लपेटने के लिए एक HOC (उच्च-क्रम घटक) बनाएँ:

const WithLink = ({ link, className, children }) => (link ?
  <a href={link} className={className}>
    {children}
  </a>
  : children
);

return (
  <WithLink link={this.props.link} className={baseClasses}>
    <i className={styles.Icon}>
      {this.props.count}
    </i>
  </WithLink>
);

4
HOC को धीरे-धीरे मरना चाहिए: P
Jamie Hutber

शब्द HOCछुपा हुआ है। यह महज एक फंक्शन है जिसे बीच में रखा गया है। मैं वास्तव में इस अचानक ट्रेंडी नाम "एचपीसी" को विस्थापित करता हूं। एक साधारण फ़ंक्शन के बारे में इतना उच्च-क्रम क्या है जो दशकों के बीच ... पुरानी अवधारणा के बीच रखा गया है।
vsync

12

यहां एक उपयोगी घटक का एक उदाहरण दिया गया है जिसका मैंने उपयोग किया है (यह सुनिश्चित करने के लिए कि कौन इसे मान्यता देता है) जो काम करता है:

const ConditionalWrap = ({ condition, wrap, children }) => (
  condition ? wrap(children) : children
);

उदाहरण:

<ConditionalWrap condition={someCondition}
  wrap={children => (<a>{children}</a>)} // Can be anything
>
  This text is passed as the children arg to the wrap prop
</ConditionalWrap>

2
क्रेडिट की संभावना यहां जानी चाहिए: gist.github.com/kitze/23d82bb9eb0baabfd03a6a720b1d637f
रॉय

मैंने देखा कि किटज़ से। लेकिन मुझे यकीन नहीं था कि उसे किसी और से विचार मिल गया था
एंटोनी

न तो मैं हूं। यह पहला परिणाम था जो पॉप अप हुआ और मैंने इसे स्रोत माना - या कम से कम इसके करीब;)।
रॉय

आपको wrapचीजों को अधिक "रिएक्ट" करने के लिए डिक्लेरेटिवली का उपयोग करना चाहिए, न कि फंक्शन के रूप में -स्पिरिट
vsync

आप इसे और अधिक घोषणात्मक @vsync कैसे बनाएंगे? मुझे लगता है कि रेंडर प्रॉप्स रिएक्ट की भावना के भीतर थे?
एंटनी

10

एक अन्य तरीका है जिससे आप एक संदर्भ चर का उपयोग कर सकते हैं

let Wrapper = React.Fragment //fallback in case you dont want to wrap your components

if(someCondition) {
    Wrapper = ParentComponent
}

return (
    <Wrapper parentProps={parentProps}>
        <Child></Child>
    </Wrapper>

)

आप करने के लिए पहली छमाही गाढ़ा कर सकते हैंlet Wrapper = someCondition ? ParentComponent : React.Fragment
mpoisot

यह बहुत बढ़िया है, लेकिन कभी-कभी आप कोड को घोषणात्मक रखना चाहते हैं , जिसका अर्थ है कि यह केवल JSX
vsync

मुझे एक त्रुटि मिलती है React.Fragment can only have 'key' and 'children'क्योंकि मैं "<रैपर>" जैसे "क्लासनेम" के लिए कुछ प्रॉप्स पास करता हूं और इसलिए
vsync

@vsync आपको सहारा के लिए एक शर्त जोड़ने की ज़रूरत है और साथ ही साथ कुछ भी करना चाहिए जैसे कि PropId = {someCondition? पेरेंटप्रॉप्स: अपरिभाषित} ..
अविनाश

1
मुझे पता है :) मैं इसे इस मुद्दे के साथ आने वाले अन्य लोगों के लिए दस्तावेज़ीकरण के लिए लिख रहा था, इसलिए Google इस पृष्ठ को उन कीवर्ड के लिए अपने खोज परिणामों में कैश कर देगा
vsync

1

आप इस तरह एक उपयोग फ़ंक्शन का उपयोग कर सकते हैं:

const wrapIf = (conditions, content, wrapper) => conditions
        ? React.cloneElement(wrapper, {}, content)
        : content;

0

अगर आपको यहाँ वर्णित है तो आपको JSX का उपयोग करना चाहिए । कुछ इस तरह से काम करना चाहिए।

App = React.creatClass({
    render() {
        var myComponent;
        if(typeof(this.props.url) != 'undefined') {
            myComponent = <myLink url=this.props.url>;
        }
        else {
            myComponent = <myDiv>;
        }
        return (
            <div>
                {myComponent}
            </div>
        )
    }
});

-2

एक कार्यात्मक घटक जो 2 घटकों का प्रतिपादन करता है, एक लपेटा हुआ है और दूसरा नहीं है।

विधि 1:

// The interesting part:
const WrapIf = ({ condition, With, children, ...rest }) => 
  condition 
    ? <With {...rest}>{children}</With> 
    : children

 
    
const Wrapper = ({children, ...rest}) => <h1 {...rest}>{children}</h1>


// demo app: with & without a wrapper
const App = () => [
  <WrapIf condition={true} With={Wrapper} style={{color:"red"}}>
    foo
  </WrapIf>
  ,
  <WrapIf condition={false} With={Wrapper}>
    bar
  </WrapIf>
]

ReactDOM.render(<App/>, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

इसे इस तरह भी इस्तेमाल किया जा सकता है:

<WrapIf condition={true} With={"h1"}>

विधि 2:

// The interesting part:
const Wrapper = ({ condition, children, ...props }) => condition 
  ? <h1 {...props}>{children}</h1>
  : <React.Fragment>{children}</React.Fragment>;   
    // stackoverflow prevents using <></>
  

// demo app: with & without a wrapper
const App = () => [
  <Wrapper condition={true} style={{color:"red"}}>
    foo
  </Wrapper>
  ,
  <Wrapper condition={false}>
    bar
  </Wrapper>
]

ReactDOM.render(<App/>, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.