मैं प्रतिक्रिया सीखने और HTTP अनुरोध करने की प्रक्रिया में हूं।

हाल ही में मैं उस वेबपृष्ठ के लिए ड्रॉपडाउन लागू करने का प्रयास कर रहा हूं जिस पर मैं काम कर रहा हूं। मेरे कोड में मुझे आईडी की एक सरणी के माध्यम से लूप करना था, और प्रत्येक आईडी के लिए मेटाडेटा निकालने के लिए एक पोस्ट अनुरोध करना था। तो मुझे ड्रॉपडाउन विकल्पों में कोई समस्या आ रही है। ड्रॉपडाउन विकल्पों को संबंधित आईडी के नाम माना जाता है।

आईडी की सरणी वस्तुओं की एक सरणी है जो इस तरह दिखती है

[{key: "someidnumber1", count: 5}, {key: "someidnumber2", count: 5}, {key: "someidnumber3", count: 10},....]

तो मैंने सबसे पहले आईडी सरणी के माध्यम से लूप करना है, और प्रत्येक आईडी पर पैरामीटर के रूप में एक पोस्ट अनुरोध करना है। यह मेरी रेंडर विधि के अंदर है।

render() {
  return(
    <SomeOtherComponent>
      { //Do something to fetch the ids
        let promises = [];
        let names = [];
        let options = [];

        ids.map(id => {
          promises.push(
            axios
              .post(TARGET_META_URL, {
                filters: [
                  {
                    field: "id",
                    values: [id.key]
                  }
                ]
              })
              .then(response => {
                 // adding the name from the data into the names array
                 names.push(response.data[0].name);
              })
        });

        Promise.all(promises).then(() => {
          // Wait for the promises to collection all the names
          // and pass into a new array
          options = [...names];
        }

        return (
          <Dropdown 
            options={options}
          />
        );
       }
    </SomeOtherComponent>
  );
}

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

1
user14459580 4 नवम्बर 2020, 05:29

2 जवाब

सबसे बढ़िया उत्तर

एक और घटक बनाएं जो डेटा प्राप्त करता है और प्रतिक्रिया वापस आने के बाद उन्हें प्रस्तुत करता है। सभी वादों के एक साथ हल होने की प्रतीक्षा करने के लिए Promise.all का उपयोग करें।

const getName = id => axios
    .post(TARGET_META_URL, {
        filters: [
            {
                field: "id",
                values: [id.key]
            }
        ]
    })
    .then(response => response.data[0].name);
const AsyncDropdown = ({ ids }) => {
    const [options, setOptions] = useState();
    useEffect(() => {
        Promise.all(ids.map(getName))
            .then(setOptions)
            .catch((err) => {
                // handle errors
            });
    }, [ids]);
    return options ? <Dropdown options={options} /> : null;
}

और अपनी मूल रेंडर विधि को इसके साथ बदलें:

render() {
  return(
    <SomeOtherComponent>
      <AsyncDropdown ids={ids} />
    </SomeOtherComponent>
  );
}
2
CertainPerformance 4 नवम्बर 2020, 05:34

शायद यह मदद करेगा -

componentDidMount() {
    let promises = [];
    let options = [];
    ids.map(id => {
        promises.push(
            axios
            .post(TARGET_META_URL, {
            filters: [
                {
                    field: "id",
                    values: [id.key]
                }
            ]
        })
    });

    Promise.all(promises).then((response) => {
    // Wait for the promises to collection all the names
    // and pass into a new array
    options = response.map(res => res.data[0].name);
    this.setState({ options })
    }
}

render() {
    return(
        <SomeOtherComponent>
        { this.state.options?.length ? <Dropdown options={this.state.options} /> : null }
        </SomeOtherComponent>
    );
}
1
Vikrant 6 नवम्बर 2020, 12:11