प्रतिक्रिया Js में API कॉल करने का सही तरीका क्या है?


137

मैं हाल ही में Angular से ReactJs में स्थानांतरित हुआ हूं। मैं एपीआई कॉल के लिए jQuery का उपयोग कर रहा हूं। मेरे पास एक एपीआई है जो एक यादृच्छिक उपयोगकर्ता सूची देता है जिसे एक सूची में मुद्रित किया जाना है।

मुझे यकीन नहीं है कि मेरे एपीआई कॉल कैसे लिखें। इसके लिए सबसे अच्छा अभ्यास क्या है?

मैंने निम्नलिखित की कोशिश की लेकिन मुझे कोई आउटपुट नहीं मिल रहा है। यदि आवश्यक हो तो मैं वैकल्पिक एपीआई पुस्तकालयों को लागू करने के लिए खुला हूं।

नीचे मेरा कोड है:

import React from 'react';

export default class UserList extends React.Component {    
  constructor(props) {
    super(props);
    this.state = {
      person: []
    };
  }

  UserList(){
    return $.getJSON('https://randomuser.me/api/')
    .then(function(data) {
      return data.results;
    });
  }

  render() {
    this.UserList().then(function(res){
      this.state = {person: res};
    });
    return (
      <div id="layout-content" className="layout-content-wrapper">
        <div className="panel-list">
          {this.state.person.map((item, i) =>{
            return(
              <h1>{item.name.first}</h1>
              <span>{item.cell}, {item.email}</span>
            )
          })}
        <div>
      </div>
    )
  }
}

2
मैं इस बात पर निर्भर करता हूं कि आप किस राज्य प्रबंधन पुस्तकालय का उपयोग कर रहे हैं। यदि आप किसी का उपयोग नहीं कर रहे हैं, तो आप अपनी एपीआई कॉल को अलग फाइल में स्थानांतरित कर सकते हैं, और componentDidMountकॉलबैक में आपकी स्थिति में एपीआई कार्यों को कॉल कर सकते हैं ।
11:33

आप fetch()jQuery के बजाय उपयोग कर सकते हैं यदि आप केवल Ajax अनुरोध करने के लिए jQuery का उपयोग करते हैं।
फ्रेड

Jquery का उपयोग क्यों करें? Jquery एक विशाल पुस्तकालय है और यह अनावश्यक है
Robin

बस यहाँ जोड़ते हुए कि वर्तमान useEffectमें शायद अब आपी कॉल लगाने की जगह है। देखें btholt.github.io/complete-intro-to-react-v5/effects
SHW

जवाबों:


98

इस स्थिति में, आप अंदर ajax कॉल कर सकते हैं componentDidMountऔर फिर अपडेट कर सकते हैंstate

export default class UserList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {person: []};
  }

  componentDidMount() {
    this.UserList();
  }

  UserList() {
    $.getJSON('https://randomuser.me/api/')
      .then(({ results }) => this.setState({ person: results }));
  }

  render() {
    const persons = this.state.person.map((item, i) => (
      <div>
        <h1>{ item.name.first }</h1>
        <span>{ item.cell }, { item.email }</span>
      </div>
    ));

    return (
      <div id="layout-content" className="layout-content-wrapper">
        <div className="panel-list">{ persons }</div>
      </div>
    );
  }
}

2
यह काम किया, धन्यवाद .. क्या आप कृपया मुझे सुझाव दे सकते हैं "जो बेहतर राज्य प्रबंधन के लिए सबसे अच्छा पुस्तकालय है"
राज आरजे

3
@ राज आरजे इन दिनों में मुझे लगता है कि यह Redux है
अलेक्जेंडर टी।

8
इन दिनों में Redux अधिक लोकप्रिय है, इसकी शैली कार्यात्मक प्रोग्रामिंग से आती है। यदि आप ओओपी शैली से आते हैं, तो Mobx ( mobxjs.github.io/mobx ) एक उत्कृष्ट राज्य प्रबंधन पुस्तकालय है, यह आपको बिजनेस कोड लिखने पर ध्यान केंद्रित करने देता है और अंततः आपके बायलरप्लेट कोड को कम करता है
Nhan Tran

25

आप फ्लक्स आर्किटेक्चर की जांच कर सकते हैं । मैं रिएक्ट-रिडक्स कार्यान्वयन की जांच करने की भी सलाह देता हूं । अपने कार्यों में अपने एपीआई कॉल रखो। यह सभी घटक में डालने की तुलना में बहुत अधिक क्लीनर है।

क्रियाएं सहायक विधियों की तरह होती हैं जिन्हें आप अपनी एप्लिकेशन स्थिति बदलने या एपीआई कॉल करने के लिए कह सकते हैं।


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

Redux कार्यान्वयन में, एक्शन विधियों को घटकों के लिए इंजेक्ट किया जाता है। ये विधियाँ अब आपके घटक के लिए सहारा बन जाएँगी जिसे आप कॉल कर सकते हैं। आप संरचना के लिए प्रतिक्रिया-रिड्यूक्स-स्टार्टर-किट देख सकते हैं ।
Jei Trooper

12

अद्यतन स्थिति के लिए fetchअंदर की विधि का उपयोग करें componentDidMount:

componentDidMount(){
  fetch('https://randomuser.me/api/')
      .then(({ results }) => this.setState({ person: results }));
}

11

यह चर्चा कुछ समय के लिए रही है और @Alexander T. के जवाब ने मेरे जैसे नए रिएक्ट का अनुसरण करने के लिए एक अच्छा मार्गदर्शक प्रदान किया। और मैं घटक को ताज़ा करने के लिए एक ही एपीआई को कई बार कॉल करने के बारे में कुछ अतिरिक्त जानकारी साझा करने वाला हूं, मुझे लगता है कि यह शायद एक आम समस्या है जो नौसिखिया शुरुआत में सामना कर सकती है।

componentWillReceiveProps(nextProps), से आधिकारिक दस्तावेज :

यदि आपको प्रोपर परिवर्तनों (उदाहरण के लिए, इसे रीसेट करने के लिए) की प्रतिक्रिया में राज्य को अपडेट करने की आवश्यकता है, तो आप इस तरीके की तुलना कर सकते हैं। क्रॉप्स और नेक्स्टप्रॉप्स और स्टेट ट्रांज़ैक्शन का उपयोग करते हुए इस पद्धति का उपयोग करें।

हम यह निष्कर्ष निकाल सकते हैं कि यहां वह स्थान है जिसे हम मूल घटक से प्रॉपर संभालते हैं, एपीआई कॉल और अद्यतन स्थिति है।

@Alexander T के उदाहरण पर आधार:

export default class UserList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {person: []};
  }

  componentDidMount() {
   //For our first load. 
   this.UserList(this.props.group); //maybe something like "groupOne"
  }

  componentWillReceiveProps(nextProps) {
    // Assuming parameter comes from url.
    // let group = window.location.toString().split("/")[*indexParameterLocated*];
    // this.UserList(group);

    // Assuming parameter comes from props that from parent component.
    let group = nextProps.group; // Maybe something like "groupTwo" 
    this.UserList(group);
  }

  UserList(group) {
    $.getJSON('https://randomuser.me/api/' + group)
      .then(({ results }) => this.setState({ person: results }));
  }

  render() {
    return (...)
  }
}

अपडेट करें

componentWillReceiveProps() पदावनत किया जाएगा।

यहाँ जीवन चक्र में केवल कुछ विधियाँ (उन सभी में डॉक्टर ) हैं जो मुझे लगता है कि सामान्य स्थिति में एपीआई की तैनाती से संबंधित होगी: यहाँ छवि विवरण दर्ज करें

ऊपर आरेख का संदर्भ देकर:

  • एपीआई में तैनात करें componentDidMount()

    यहाँ एपीआई कॉल करने का उचित परिदृश्य यह है कि इस घटक की सामग्री (एपीआई की प्रतिक्रिया से) स्थिर होगी, componentDidMount()केवल एक बार आग लगने पर घटक बढ़ रहा है, यहां तक ​​कि नए प्रॉप्स को मूल घटक से पारित किया जाता है या नेतृत्व करने के लिए क्रियाएं होती हैं re-rendering
    घटक पुन: रेंडर करने के लिए अंतर की जांच करता है लेकिन पुन: माउंट नहीं करता हैडॉक्टर
    से उद्धरण :

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


  • एपीआई में तैनात करें static getDerivedStateFromProps(nextProps, prevState)

हमें ध्यान देना चाहिए कि दो प्रकार के घटक अद्यतन होते हैं , setState() वर्तमान घटक में इस विधि को ट्रिगर करने के लिए नेतृत्व नहीं किया जाएगा , लेकिन मूल घटक से पुन: प्रतिपादन या नए सहारा । हमें पता चला कि बढ़ते समय यह विधि भी आग लगाती है।

यह एपीआई को तैनात करने के लिए एक उचित स्थान है यदि हम एक टेम्पलेट की तरह वर्तमान घटक का उपयोग करना चाहते हैं, और एपीआई के लिए नए पैरामीटर मूल घटक से आने वाले प्रॉप्स हैं
हमें एपीआई से एक अलग प्रतिक्रिया मिलती है और stateइस घटक की सामग्री को बदलने के लिए यहां एक नया रिटर्न मिलता है ।

उदाहरण के लिए:
हमारे पास मूल घटक में विभिन्न कारों के लिए एक ड्रॉपडाउन सूची है, इस घटक को चयनित के विवरण को दिखाने की आवश्यकता है।


  • एपीआई में तैनात करें componentDidUpdate(prevProps, prevState)

से अलग static getDerivedStateFromProps(), इस विधि प्रारंभिक प्रतिपादन को छोड़कर हर प्रतिपादन के तुरंत बाद शुरू हो जाती है। हमारे पास एक घटक में एपीआई कॉलिंग और रेंडर अंतर हो सकता है।

पिछले उदाहरण का विस्तार करें:
कार के विवरण दिखाने के लिए घटक में इस कार की श्रृंखला की एक सूची शामिल हो सकती है, यदि हम 2013 के उत्पादन की जांच करना चाहते हैं, तो हम setState()इस पर विचार करने के लिए पहली बार नेतृत्व करने के लिए क्लिक या चुन सकते हैं ... सूची आइटम व्यवहार (जैसे सूची आइटम को हाइलाइट करना) इस घटक में, और निम्नलिखित में componentDidUpdate()हम नए पैरामीटर (राज्य) के साथ अपना अनुरोध भेजते हैं। प्रतिक्रिया मिलने के बाद, हम setState()फिर से कार विवरण के विभिन्न कंटेंट को प्रस्तुत करने के लिए। componentDidUpdate()इन्फिनिटी लूप को उत्पन्न करने से निम्नलिखित को रोकने के लिए , हमें prevStateयह तय करने के लिए इस विधि की शुरुआत में उपयोग करके राज्य की तुलना करने की आवश्यकता है कि क्या हम एपीआई भेजते हैं और नई सामग्री को प्रस्तुत करते हैं।

यह विधि वास्तव में static getDerivedStateFromProps()प्रॉप्स की तरह ही उपयोग की जा सकती है , लेकिन propsउपयोग द्वारा परिवर्तनों को संभालने की आवश्यकता है prevProps। और हमें componentDidMount()प्रारंभिक एपीआई कॉल को संभालने के लिए सहयोग करने की आवश्यकता है ।

डॉक्टर से उद्धरण :

... यह नेटवर्क अनुरोधों को करने के लिए भी एक अच्छा स्थान है जब तक कि आप वर्तमान प्रॉप्स की तुलना पिछले प्रॉप्स से करते हैं ...


10

मैं चाहूंगा कि आप redux http://redux.js.org/index.html पर एक नज़र डालें

वे बहुत अच्छी तरह से परिभाषित किया है async से निपटने के रास्ते यानी API कॉल कहता है, और इसके बजाय API कॉल के लिए jQuery का उपयोग कर के, मैं उपयोग करने की अनुशंसा करना चाहते हैं लाने या अनुरोध , NPM संकुल लाने वर्तमान में आधुनिक ब्राउज़रों द्वारा समर्थित है, लेकिन एक शिम के लिए भी उपलब्ध है सर्वर साइड।

यह एक और अद्भुत पैकेज सुपरगेंट भी है , जिसमें एपीआई अनुरोध करते समय बहुत सारे विकल्प हैं और इसका उपयोग करना बहुत आसान है।


3

रेंडर फ़ंक्शन शुद्ध होना चाहिए, इसका मतलब है कि यह केवल रेंडर करने के लिए राज्य और प्रॉप्स का उपयोग करता है, रेंडर में राज्य को संशोधित करने की कोशिश कभी न करें, यह आमतौर पर बदसूरत कीड़े का कारण बनता है और प्रदर्शन में काफी कमी करता है। यदि आप डेटा को अलग करते हैं और अपने रिएक्ट ऐप में चिंताओं को दूर करते हैं तो यह भी एक अच्छी बात है। मैं आपको इस लेख को पढ़ने की सलाह देता हूं जो इस विचार को बहुत अच्छी तरह से समझाता है। https://medium.com/@learnreact/container-components-c0e67432e005#.sfydn87nm


3

React v16 प्रलेखन का यह भाग आपके प्रश्न का उत्तर देगा, के बारे में पर पढ़ें घटकडिमाउंट ():

componentDidMount ()

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

जैसा कि आप देख रहे हैं, एपीआई कॉल करने के लिए कंपोनेंटडिमाउंट को सबसे अच्छी जगह और चक्र माना जाता है , नोड भी एक्सेस करें , इस समय तक कॉल करने के लिए सुरक्षित है, दृश्य को अपडेट करें या जब आप तैयार हों तो जो कुछ भी आप कर सकते हैं, यदि आप हैं तो jQuery का उपयोग करते हुए, इसे किसी तरह से आपको document.ready () फ़ंक्शन को याद दिलाना चाहिए, जहाँ आप यह सुनिश्चित कर सकते हैं कि जो कुछ भी आप अपने कोड में करना चाहते हैं उसके लिए सब कुछ तैयार है ...


3

1) आप एंड पॉइंट से डेटा लाने के लिए F etch API का उपयोग कर सकते हैं :

Githubउपयोगकर्ता के लिए सभी रिपोज को लाने का उदाहरण

  /* Fetch GitHub Repos */
  fetchData = () => {

       //show progress bar
      this.setState({ isLoading: true });

      //fetch repos
      fetch(`https://api.github.com/users/hiteshsahu/repos`)
      .then(response => response.json())
      .then(data => {
        if (Array.isArray(data)) {
          console.log(JSON.stringify(data));
          this.setState({ repos: data ,
                         isLoading: false});
        } else {
          this.setState({ repos: [],
                          isLoading: false  
                        });
        }
      });
  };

2) अन्य वैकल्पिक Axios है

Axios का उपयोग करके आप .json () विधि से http अनुरोध के परिणामों को पारित करने के मध्य चरण को काट सकते हैं। एक्सियोस सिर्फ वह डेटा ऑब्जेक्ट लौटाता है जिसकी आपको अपेक्षा होती है।

  import axios from "axios";

 /* Fetch GitHub Repos */
  fetchDataWithAxios = () => {

     //show progress bar
      this.setState({ isLoading: true });

      // fetch repos with axios
      axios
          .get(`https://api.github.com/users/hiteshsahu/repos`)
          .then(result => {
            console.log(result);
            this.setState({
              repos: result.data,
              isLoading: false
            });
          })
          .catch(error =>
            this.setState({
              error,
              isLoading: false
            })
          );
}

अब आप इनमें से किसी भी रणनीति का उपयोग करके डेटा प्राप्त करना चुन सकते हैं componentDidMount

class App extends React.Component {
  state = {
    repos: [],
   isLoading: false
  };

  componentDidMount() {
    this.fetchData ();
  }

इस बीच आप डेटा लोड होने के दौरान प्रगति बार दिखा सकते हैं

   {this.state.isLoading && <LinearProgress />}

2

आप अपने फ़ंक्शन घटकों में हुक के साथ डेटा भी ला सकते हैं

एपीआई कॉल के साथ पूरा उदाहरण: https://codesandbox.io/s/jvvkoo8pq3

दूसरा उदाहरण: https://jsfiddle.net/bradcypert/jhrt40yv/6/

const Repos = ({user}) => {
  const [repos, setRepos] = React.useState([]);

  React.useEffect(() => {
    const fetchData = async () => {
        const response = await axios.get(`https://api.github.com/users/${user}/repos`);
        setRepos(response.data);
    }

    fetchData();
  }, []);

  return (
  <div>
    {repos.map(repo =>
      <div key={repo.id}>{repo.name}</div>
    )}
  </div>
  );
}

ReactDOM.render(<Repos user="bradcypert" />, document.querySelector("#app"))

1

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

प्रतिक्रिया में प्रारंभिक बाहरी डेटा स्रोत कॉल के लिए अन्य विकल्प के रूप में वर्ग के निर्माता () विधि को इंगित किया गया है । कंस्ट्रक्टर घटक वस्तु उदाहरण के प्रारंभ पर निष्पादित पहली विधि है। आप उच्च-क्रम घटकों के लिए दस्तावेज़ीकरण उदाहरणों में इस दृष्टिकोण को देख सकते हैं ।

बाहरी API कॉल के लिए विधि घटक WillMount () और UNSAFE_componentWillMount () का उपयोग नहीं किया जाना चाहिए, क्योंकि उनका पदावनत करने का इरादा है। यहां आप सामान्य कारण देख सकते हैं कि इस विधि को क्यों हटाया जाएगा।

वैसे भी आपको बाह्य एपीआई कॉल के लिए एक बिंदु के रूप में रेंडर () विधि या रेंडर से सीधे कॉल नहीं करना चाहिए । यदि आप ऐसा करते हैं तो आपका आवेदन अवरुद्ध हो जाएगा


0

एक साफ तरीका है कोशिश / कैच फंक्शन के साथ कम्पोनेंटडिमाउंट के अंदर एक एसिंक्रोनस एपीआई कॉल करना

जब हम एक एपीआई कहते हैं, तो हमें एक प्रतिक्रिया मिलती है। तब हम उस पर JSON विधि लागू करते हैं, प्रतिक्रिया को जावास्क्रिप्ट ऑब्जेक्ट में बदलने के लिए। तब हम उस प्रतिक्रिया ऑब्जेक्ट से केवल "परिणाम" (data.results) नाम की उसकी चाइल्ड ऑब्जेक्ट लेते हैं।

शुरुआत में हमने राज्य में "यूजरलिस्ट" को एक खाली सरणी के रूप में परिभाषित किया। जैसे ही हम एपीआई कॉल करते हैं और उस एपीआई से डेटा प्राप्त करते हैं, हम setState पद्धति का उपयोग करके उपयोगकर्ता को "परिणाम" देते हैं ।

रेंडर फंक्शन के अंदर हम बताते हैं कि यूजरलिस्ट राज्य से आएगा। चूंकि उपयोगकर्ता सूची वस्तुओं का एक सरणी है, जिसके माध्यम से हम चित्र बनाते हैं, प्रत्येक वस्तु "उपयोगकर्ता" का एक चित्र, एक नाम और एक फोन नंबर प्रदर्शित करने के लिए। इस जानकारी को पुनः प्राप्त करने के लिए हम डॉट नोटेशन (जैसे user.phone) का उपयोग करते हैं।

नोट : आपके एपीआई के आधार पर, आपकी प्रतिक्रिया अलग दिख सकती है। Console.log पूरे "प्रतिक्रिया" को देखने के लिए कि आपको किस चर से इसकी आवश्यकता है, और फिर उन्हें setState में असाइन करें।

UserList.js

import React, { Component } from "react";

export default class UserList extends Component {
   state = {
      userList: [], // list is empty in the beginning
      error: false
   };

   componentDidMount() {
       this.getUserList(); // function call
   }

   getUserList = async () => {
       try { //try to get data
           const response = await fetch("https://randomuser.me/api/");
           if (response.ok) { // ckeck if status code is 200
               const data = await response.json();
               this.setState({ userList: data.results});
           } else { this.setState({ error: true }) }
       } catch (e) { //code will jump here if there is a network problem
   this.setState({ error: true });
  }
};

  render() {
  const { userList, error } = this.state
      return (
          <div>
            {userList.length > 0 && userList.map(user => (
              <div key={user}>
                  <img src={user.picture.medium} alt="user"/>
                  <div>
                      <div>{user.name.first}{user.name.last}</div>
                      <div>{user.phone}</div>
                      <div>{user.email}</div>
                  </div>
              </div>
            ))}
            {error && <div>Sorry, can not display the data</div>}
          </div>
      )
}}

0

एपि अनुरोध के लिए अक्षतंतु का उपयोग करना बहुत अच्छा होगा जो अक्षतंतु, इंटरसेप्टर आदि का समर्थन करता है। साथ ही axios के साथ, राज्य प्रबंधन के लिए l- अभिक्रिया-रिड्यूक्स और साइड इफेक्ट के लिए redux-saga / redux-thunk का उपयोग करें।


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