घटकों के async रेंडरिंग को अभिक्रिया करता है


83

मैं अपने ajax अनुरोध किए जाने के बाद अपने घटक को प्रस्तुत करना चाहता हूं।

नीचे आप मेरा कोड देख सकते हैं

var CategoriesSetup = React.createClass({

    render: function(){
        var rows = [];
        $.get('http://foobar.io/api/v1/listings/categories/').done(function (data) {
            $.each(data, function(index, element){
                rows.push(<OptionRow obj={element} />);
            });
           return (<Input type='select'>{rows}</Input>)

        })

    }
});

लेकिन मुझे नीचे त्रुटि मिलती है क्योंकि मैं अपने ajax अनुरोध के किए गए तरीके के अंदर रेंडर कर रहा हूं।

Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

वहाँ एक तरीका है मेरे ajax अनुरोध के लिए प्रतीक्षा शुरू करने से पहले समाप्त करने के लिए है?


3
इसके अलावा, एक छोटी सी नाइटपिक लेकिन एक रेंडर () रुटीन में डेटा रिट्रीवल होना वास्तव में एक महान विचार नहीं है। रेंडरिंग (शेष) को रेंडर करने और सार करने के लिए रखें। इसके अलावा, आप केवल उस डेटा को एक बार प्राप्त करना चाहते हैं, हर बार घटक प्रदान नहीं किया जा सकता है।
फिल कूपर

जवाबों:


132

इसे संभालने के दो तरीके हैं, और जो आप चुनते हैं वह इस बात पर निर्भर करता है कि किस घटक के पास डेटा और लोडिंग स्थिति होनी चाहिए।

  1. माता-पिता में अजाक्स अनुरोध को स्थानांतरित करें और घटक को सशर्त रूप से प्रस्तुत करें:

    var Parent = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <CategoriesSetup data={this.state.data} />;
        }
    
        return <div>Loading...</div>;
      }
    });
    
  2. घटक में अजाक्स अनुरोध रखें और इसे लोड करते समय सशर्त रूप से कुछ और प्रस्तुत करें:

    var CategoriesSetup = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <Input type="select">{this.state.data.map(this.renderRow)}</Input>;
        }
    
        return <div>Loading...</div>;
      },
    
      renderRow: function(row) {
        return <OptionRow obj={row} />;
      }
    });
    

6
मैं 2017 में इस उत्तर को पार कर गया हूं, क्या ये दो सबसे अच्छे समाधान अभी भी उपयोग करने के लिए सर्वश्रेष्ठ हैं?
डैन

@ डान रिएक्ट प्रॉप और राज्य के आधार पर यूआई प्रदान करता है, इसलिए कोर अवधारणा एक ही रहेगी - अजाक्स अनुरोध करें, कुछ राज्य सेट करें, और कुछ फिर से प्रस्तुत करें। हालांकि, उच्च क्रम के घटकों जैसे पैटर्न अधिक लोकप्रिय हो गए हैं, यह दर्शाता है कि कोई जटिलता को कैसे दूर कर सकता है।
मिशेल टिली

1
if (this.state.data)होना चाहिए if (this.state && this.state.data)क्योंकि कभी-कभी राज्य शून्य हो सकता है।
तिमो

@Timo हम्म, क्या मामले में होता this.stateहो null?
मिशेल टिली

6
@ टिमो ने कंस्ट्रक्टर में राज्य की शुरुआत की
लुइस

8

घटकों के async प्रतिपादन का मूल उदाहरण नीचे दिया गया है:

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

export default class YourComponent extends React.PureComponent {
    constructor(props){
        super(props);
        this.state = {
            data: null
        }       
    }

    componentDidMount(){
        const data = {
                optPost: 'userToStat01',
                message: 'We make a research of fetch'
            };
        const endpoint = 'http://example.com/api/phpGetPost.php';       
        const setState = this.setState.bind(this);      
        fetch(endpoint, {
            method: 'POST',
            body: JSON.stringify(data)
        })
        .then((resp) => resp.json())
        .then(function(response) {
            setState({data: response.message});
        });
    }

    render(){
        return (<div>
            {this.state.data === null ? 
                <div>Loading</div>
            :
                <div>{this.state.data}</div>
            }
        </div>);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.