सवाल ReactJs - एक "अगर" घटक बनाना ... एक अच्छा विचार?


मैंने रिएक्ट डॉक्स में पढ़ा है कि जेएसएक्स कोड में "if" टाइप कथन का उपयोग नहीं किया जा सकता है, जिस तरह जेएसएक्स जावास्क्रिप्ट में प्रस्तुत करता है, यह काम नहीं करता है क्योंकि कोई उम्मीद करेगा।

लेकिन क्या कोई कारण है कि "अगर" घटक को लागू करना एक बुरा विचार है? ऐसा लगता है कि मेरे प्रारंभिक परीक्षणों से ठीक काम करता है, और मुझे आश्चर्य होता है कि यह अक्सर क्यों नहीं किया जाता है?

मेरे इरादे का हिस्सा प्रतिक्रिया विकास को जितना संभव हो सके, मार्कअप आधारित - जितना संभव हो उतना छोटा जावास्क्रिप्ट के साथ अनुमति देना है। मेरे लिए यह दृष्टिकोण, "डेटा संचालित" दृष्टिकोण की तरह लगता है।

आप ऐसा कर सकते हैं जेएस फिडल पर इसे यहां देखें

<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/JSXTransformer.js"></script>
<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/react-with-addons.js"></script>

<script type="text/jsx">
/** @jsx React.DOM */
    
var If = React.createClass({
  displayName: 'If',

  render: function()
  {
    if (this.props.condition)
      return <span>{this.props.children}</span>
    return null;
  }
});

var Main = React.createClass({
    render: function() {
        return (
           <div>
             <If condition={false}>
                <div>Never showing false item</div>
             </If>
             <If condition={true}>
                <div>Showing true item</div>
             </If>
          </div>
        );
    }
});

React.renderComponent(<Main/>, document.body);
</script>

उपर्युक्त परिणामों को यहां चला रहा है:

सही वस्तु दिखा रहा है


44
2017-08-10 01:47


मूल


के संभावित डुप्लिकेट सशर्त तत्व कैसे हैं और फेसबुक प्रतिक्रिया के जेएसएक्स के साथ DRY रखें? - FakeRainBrigand
यह वास्तव में समय-समय पर पूछा जाता है जब लोग प्रतिक्रिया के साथ शुरू करते हैं, लेकिन कुछ हफ्तों तक इसका उपयोग करने के बाद वे इसे रोकना बंद कर देते हैं। बस टर्नरी या प्रयोग करें && अन्य प्रश्नों में उल्लिखित चीजों को सशर्त रूप से प्रस्तुत करने के लिए। - FakeRainBrigand
अरे! फीडबैक के लिए धन्यवाद .... मैं एक चर के लिए सशर्त रूप से प्रतिपादन के दृष्टिकोण का उपयोग कर रहा हूं, फिर उस चर को मेरे अंदर डाल रहा हूं render प्रतिक्रिया, और यह ठीक काम कर रहा है। इस दृष्टिकोण के साथ बात यह है कि यह जेएसएक्स को तोड़ देता है और मेरे प्रतिक्रियाओं में एचटीएमएल की पूरी संरचना को देखना मुश्किल बनाता है। यही कारण है कि मैंने शायद सोचा था If घटक उन मामलों में मदद कर सकता है, और ऐसा करता है - उन परिस्थितियों में प्रतिक्रिया का पूर्ण मार्कअप देखना आसान होता है - लेकिन मैंने कभी भी टर्नरी दृष्टिकोण / इनलाइन सशर्तताओं को महसूस नहीं किया, और शायद इसके बजाय उनमें से एक का उपयोग करेंगे। - Brad Parks
हाँ, मैं तर्क को समझता हूं। मैंने पहले वही बात सोचा। - बीटीडब्ल्यू, बंद प्रश्न अक्सर Google पर बहुत अधिक ट्रैफिक प्राप्त करते हैं, लेकिन हाँ, अगर किसी अन्य प्रश्न को बंद करने के लिए कुछ भी बंद किया जाना चाहिए। - FakeRainBrigand
लौटने के बजाय <noscript/>, लौटने पसंद करते हैं null जो प्रतिक्रिया 0.11 के बाद से संभव है। - Sophie Alpert


जवाब:


इसकी जाँच पड़ताल करो अगर जेएसएक्स में अन्यथा प्रतिक्रिया डॉक्स में खंड।

जेएसएक्स में, आप घुंघराले ब्रेसिज़ के अंदर बयान नहीं डाल सकते - केवल अभिव्यक्तियां। यदि आप जावास्क्रिप्ट में अभिव्यक्ति बनाम बयान के बीच अंतर नहीं जानते हैं तो इसे पढ़ें लेख। यह सीमा इसलिए है क्योंकि जेएसएक्स फ़ंक्शन कॉल में desugars और आप जावास्क्रिप्ट में किसी फ़ंक्शन के तर्क के रूप में if-statement का उपयोग नहीं कर सकते हैं। हालांकि, आप बुलियन ऑपरेटर का उपयोग कर सकते हैं (&&, || तथा ? :) एक समान काम करने के लिए। वे अभिव्यक्तियां हैं ताकि वे जेएसएक्स जेनरेट करने वाले कन्स्ट्रक्टर कॉल के अंदर फिट हो सकें और उनके शॉर्ट सर्किटिंग मूल्यांकन बयान में इस्तेमाल किए गए जैसा ही हो।

<div>
    {(true
        ? <div>Showing true item</div>     
        : <div>Never showing false item</div>
    )}
</div>
<p>My name is {this.name || "default name"}</p>

इसके अतिरिक्त, प्रतिक्रिया का इलाज होगा null तथा false एक "खाली घटक" के रूप में जो वास्तविक डोम में प्रस्तुत नहीं किया जाता है (वर्तमान में यह दृश्यों के पीछे एक ही नोस्क्रिप्ट चाल का उपयोग करता है)। यह तब उपयोगी होता है जब आप "अन्य" शाखा नहीं चाहते हैं। देख जेएसएक्स में झूठा ब्योरा हेतु।

<div>
    {shouldIncludeChild ? <ChildComponent/> : false}
</div>

यदि आपके द्वारा पूछे जाने वाले घटक के लिए, एक समस्या यह है कि वर्तमान स्वरूप में यह स्थिति अपने बच्चों का मूल्यांकन करेगी, भले ही स्थिति गलत है। यह त्रुटियों का कारण बन सकता है जब स्थिति का सत्य केवल तभी समझ में आता है जब स्थिति सत्य है:

<If condition={person !== null}>
    //This code throws an exception if this.person is null
    <div>{person.name}</div>
</If>

यदि आप घटक को शरीर के घटकों की सूची के बजाय शरीर को फ़ंक्शन के रूप में प्राप्त करते हैं, तो यह कार्य कर सकता है लेकिन इसके अधिक वर्बोज़:

<If condition={person !== null} body={function(){
    return <div>{person.name}</div>
}/>

अंत में, चूंकि यदि घटक स्टेटलेस है, तो आपको एक नए घटक वर्ग की बजाय सादा फ़ंक्शन का उपयोग करने पर विचार करना चाहिए, क्योंकि इससे "अगर" रिएक्ट के सुलह एल्गोरिदम के पारदर्शी हो जाएगा। यदि आप एक घटक का उपयोग करते हैं, तो ए <div> और ए <If><div> पुराने असंगत के साथ नए घटक को मर्ज करने की कोशिश करने के बजाय असंगत माना जाएगा और प्रतिक्रिया पूरी तरह से रेड्रा करेगी।

// This custom if function is for purely illustrative purposes
// However, this idea of using callbacks to represent block of code
// is useful for defining your own control flow operators in other circumstances.
function myCustomIf(condition, onTrue, onFalse){
    onTrue  = onTrue  || function(){ return null }        
    onFalse = onFalse || function(){ return null }
    if(condition){
        return onTrue();
    }else{
        return onFalse();
    }
}

<div>    
    {myCustomIf(person !== null, function(){
         return <div>{person.name}</div>
     })}
</div>

56
2017-08-10 02:38



आप ES2015 के साथ ऐसा कर सकते हैं: gist.github.com/Ginhing/58305312a75f7f6d6165bb583ecc94ba - Ginhing
"वसा तीर" फ़ंक्शन सिंटैक्स myCustomIf का उपयोग करना आसान बनाता है लेकिन मैं बस अंतर्निर्मित का उपयोग करता हूं ?: बजाय। - hugomg
हालांकि यह मुश्किल से सवाल का जवाब देता है। - Petr Peller
लेकिन यदि आप रेडक्स का उपयोग कर रहे हैं तो आप अपने मूल घटक को उस स्थिति के बारे में अवगत नहीं कर सकते हैं, जिसे आप कनेक्ट करते समय जांच रहे हैं यदि रेडक्स में घटक कुछ कंटेनर बनाते हैं। इसलिए यदि आप परीक्षण करने के लिए राज्य मानचित्रण करके कंटेनर पर कंटेनर ऐपवासलोडेड बेसिंग बना सकते हैं condition संपत्ति। यदि इस मामले में अधिक विशिष्ट कंटेनर बनाने के लिए इसका उपयोग करना है तो इसका अच्छा विचार नहीं होगा? - panurg


आपको सादा जेएस से कुछ भी चाहिए नहीं।

सुरक्षित और पठनीय (लेकिन verbose)

maybeRenderPerson: function() {
    var personName = ...;
    if ( personName ) {
        return <div className="person">{personName}</div>;
    }
}

render: function() {
    return (
       <div className="component">
          {this.maybeRenderPerson()}
       </div>
    );
}

यह थोड़ा वर्बोज़ है, लेकिन यह आपके तर्क को छोटे, केंद्रित ब्लॉक में आसानी से विभाजित करने की अनुमति देता है। जब घटक जटिल बनने लगते हैं, यह सबसे अधिक पठनीय है।


संक्षिप्त और पठनीय (लेकिन खतरनाक)

render: function() {
    var personName = ...; // present or absent name, but never ""
    return (
       <div className="component">
          {personName && (
            <div className="person">{personName}</div>
          )}
       </div>
    );
}

यह वाक्यविन्यास काफी खतरनाक हो सकता है यदि परीक्षण चर जैसे falsy मान हो सकता है 0,"" या false। विशेष रूप से संख्याओं के साथ आपको थोड़ा परीक्षण को संशोधित करना चाहिए यदि आप यह सुनिश्चित करना चाहते हैं कि यह 0 के लिए प्रस्तुत करता है:

render: function() {
    var counter= ...; // number, can be 0
    return (
       <div className="component">
          {(typeof counter !== 'undefined') && (
            <div className="counter">{counter}</div>
          )}
       </div>
    );
}

जब घटक जटिल हो जाते हैं, कई छोटे घटकों में विभाजित होते हैं, और कोड-शैली सम्मेलन होने से इसे पठनीय रखने में मदद मिल सकती है:

render: function() {
    var person= ...; 
    var counter= ...; 
    return (
       <div className="component">
          {person && (
            <Person person={person}/>
          )}
          {(typeof counter !== 'undefined') && (
            <Counter value={counter}/>
          )}
       </div>
    );
}

आधुनिक वाक्यविन्यास (लेकिन बहुत जल्दी)

do कार्यात्मक स्टेटलेस घटकों के साथ नोटेशन पठनीयता को खोए बिना अभिव्यक्ति के लिए उपयोगी हो सकता है। आप आसानी से एक बड़े घटक को बहुत छोटे और केंद्रित लोगों में विभाजित कर सकते हैं जो इसका उपयोग करते हैं do अंकन:

const Users = ({users}) => (
  <div>
    {users.map(user =>
      <User key={user.id} user={user}/>
    )}
  </div>
)  

const UserList = ({users}) => do {
  if (!users) <div>Loading</div>
  else if (!users.length) <div>Empty</div>
  else <Users users={users}/>
}

यह जेएसएक्स के अंदर मॉड्यूल पैटर्न का उपयोग करने जैसा थोड़ा सा है, इसलिए यह काफी लचीला है, लेकिन बहुत कम बॉयलरप्लेट के साथ।

इसे सक्षम करने के लिए, आपको ES7 चरण 0 संकलन टूलिंग की आवश्यकता है, और आपके पसंदीदा आईडीई से समर्थन अभी तक मौजूद नहीं है।


33
2017-08-10 13:02



अब तक का सबसे सटीक उत्तर मैंने पढ़ा है क्योंकि यह सुपर बेवकूफ है। अछा सुझाव। - sospedra
मैं मानता हूं कि यह निश्चित रूप से अच्छा और साफ है ... और अधिक कार्यों को जोड़ने से पठनीयता में सुधार हो सकता है और कॉल स्टैक ट्रेसिंग और डंपिंग के साथ भी मदद मिल सकती है! - Brad Parks
मैंने इस तरह से सबसे सरल सशर्त जांच के लिए आदर्श होने का तरीका पाया है, और कई अलग-अलग प्रतिक्रिया घटकों (यानी एक स्विच स्टेटमेंट लागू करने) के बीच चयन करते समय यह बहुत अच्छा है। - gbmhunter
यह ES7 उदाहरण वास्तव में अच्छा है! आप ES6 के साथ उसी पैटर्न का उपयोग करके हटा सकते हैं do एक तीन जोड़ना return बयान। - styfle


आप इस तरह के इनलाइन सशर्त कर सकते हैं

{true && (
<div>render item</div>
)}

{false && (
<div>don't render item</div>
)}

या आप सिर्फ एक var का उपयोग कर सकते हैं

var something;

if (true) {
something = <div>render item</div>
}

{something}

14
2017-08-10 02:49





आप सही संदर्भ के साथ एक स्व-निष्पादन कार्य भी कर सकते हैं (हालांकि बेबेल की सहायता से)! जो मैं पसंद करता हूं क्योंकि चरों को आवंटित करने की कोई आवश्यकता नहीं है और आप जितना चाहें उतना जटिल हो सकते हैं (हालांकि आपको शायद रखरखाव के लिए नहीं होना चाहिए):

render() {
  return (
    <div>
      <div>Hello!</div>
      {() => {
        if (this.props.isLoggedIn) {
          return <Dashboard />
        } else {
          return <SignIn />
        }
      }()}
      <div>Another Tag</div>
    </div>
  );
}

4
2017-07-20 15:48





प्रयोगात्मक ES7 do वाक्यविन्यास इस स्थिति के लिए वास्तव में अच्छा है। यदि आप बेबेल का उपयोग कर रहे हैं, तो सक्षम करें es7.doExpressions तब सुविधा:

render() {
  var condition = false;

  return (
    <div>
      {do {
        if (condition) {
          <span>Truthy!</span>;
        } else {
          <span>Not truthy.</span>;
        }
      }}
    </div>
  );
}

देख http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions


3
2017-07-11 02:57





ES7 do इसके लिए बंद होना बहुत अच्छा है:

उदाहरण के लिए, यदि आप उपयोग कर रहे हैं webpack - आप ES7 विशेषताएं जोड़ सकते हैं:

सबसे पहले स्थापित करें stage-0 इसके साथ विशेषताएं:

npm install babel-preset-stage-0 -save-dev;

फिर वेबपैक लोडर सेटिंग्स में, चरण-0 बेबेल प्रीसेट जोड़ें:

    loaders : [
        //...
        {
            test : /\.js$/,
            loader : "babel-loader",
            exclude : /node_modules/,
            query : {
                presets : ["react", "stage-0", "es2015"]
            }
        }
    ]

फिर आपका घटक रेंडर फ़ंक्शन इस तरह दिख सकता है:

import React , { Component } from "react";

class ComponentWithIfs extends Component {

    render() {
        return (
            <div className="my-element">
                {
                    do {
                        if ( this.state.something ) {
                            <div>First Case</div>
                        } else {
                            <div>2nd Case</div>
                        }
                    }
                }
            </div>
        );
    }
}

1
2018-05-10 12:51





मुझे लगता है कि आप मुख्य सवाल नहीं है "क्या मैं एक कार्यान्वित कर सकता हूं अगर घटक "(क्योंकि स्पष्ट रूप से आप कर सकते हैं), लेकिन" क्या कोई कारण लागू करने का कोई कारण है अगर घटक एक बुरा विचार है? "

इसका मुख्य कारण यह एक बुरा विचार है क्योंकि एक घटक एक चक्र को प्रस्तुत करता है जो किसी मौजूदा घटक में कोड की थोड़ी मात्रा में होता है। अतिरिक्त घटक रैपर का अर्थ है कि प्रतिक्रिया को अपने बच्चों पर एक संपूर्ण अतिरिक्त रेंडर चक्र चलाने की आवश्यकता है। यदि यह एक बड़ा सौदा नहीं है अगर घटक केवल एक ही स्थान पर उपयोग किया जाता है, लेकिन यदि आपका ऐप उनके साथ बिखरा हुआ है, तो आपने अभी अपना यूआई इतना धीमा कर दिया है।

कैसे इसी तरह: <div>Hi</div> से अधिक कुशल है <div><div>Hi</div></div>


1
2018-02-21 23:09



सही उत्तर बाकी सभी अपने प्रतिक्रिया कौशल दिखा रहे हैं - hannad rehman