राज्य सरणी में धकेलने का सही तरीका


122

मैं एक राज्य सरणी में डेटा धक्का मुद्दों होने लगता है। मैं इसे इस तरह हासिल करने की कोशिश कर रहा हूं:

this.setState({ myArray: this.state.myArray.push('new value') })

लेकिन मेरा मानना ​​है कि यह गलत तरीका है और उत्परिवर्तन के साथ मुद्दों का कारण बनता है?

जवाबों:


145

एरियर पुश रिटर्न की लंबाई

this.state.myArray.push('new value')विस्तारित सरणी की लंबाई देता है, सरणी के बजाय ही। Array.prototyp.push ()

मुझे लगता है कि आप ऐरे होने के लिए दिए गए मान की अपेक्षा करते हैं।

अचल स्थिति

ऐसा लगता है कि यह प्रतिक्रिया का व्यवहार है:

कभी भी इसे बदल न दें। सीधे सेट करें, जैसे कि सेटस्टैट () बाद में आपके द्वारा किए गए उत्परिवर्तन को बदल सकता है। यह समझो कि यह अपरिवर्तनीय है। React.Component

मुझे लगता है, आप इसे इस तरह से करेंगे (प्रतिक्रिया से परिचित नहीं):

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })

1
जब मैं ऐसा console.log(this.state.myArray)करता हूं तो यह हमेशा पीछे रहता है। कोई विचार क्यों?
Si8

@ Si8 खैर, मैं बहुत दुर्भाग्य से रिएक्ट का उपयोग नहीं करता हूं। लेकिन डॉक्स का कहना है: setState()घटक राज्य में परिवर्तन करता है और प्रतिक्रिया देता है कि इस घटक और उसके बच्चों को अद्यतन स्थिति के साथ फिर से प्रस्तुत करने की आवश्यकता है। इसलिए मुझे लगता है कि इसे स्थापित करने के ठीक बाद उस समय इसे अपडेट नहीं किया गया। क्या आप कृपया एक कोड उदाहरण पोस्ट कर सकते हैं, जहां हम यह देख सकते हैं कि आप किस बिंदु को सेट और लॉग इन कर रहे हैं, कृपया?
मेर्टन तमसे जुले

जवाब देने के लिए धन्यवाद। यह async है इसलिए यह आपको तुरंत परिवर्तन नहीं दिखाएगा। हालाँकि setState में एक कॉलबैक है जिसने सही मान प्रदर्शित किया है। एक बार फिर धन्यवाद।
Si8


1
@ManoharReddyPoreddy गैर-सरणी मान पूरी तरह से concat()विधि के लिए मान्य हैं । देखें: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ( Arrays और / या मानों को एक नए सरणी में
संक्षिप्त करने के लिए

176

Es6 का उपयोग करके इसे इस तरह किया जा सकता है:

this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array

फैला हुआ वाक्यविन्यास


1
मैंने ऐसा ही किया, दो मामले हैं मायरे में मान हो सकते हैं और यह नहीं होगा। इस प्रकार, अगर इसमें पहले से ही मान है, तो यह पूरी तरह से ठीक काम करता है। लेकिन किसी भी डेटा में .. यह 'नए मूल्य' के साथ राज्य को अपडेट नहीं करता है। कोई सोलन?
कृतिका सोनी

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

नमस्ते कृपया मेरी टिप्पणी को देखें। यह सिर्फ सांत्वना में एक नमूना था। मैंने अपना ऐरे की कोशिश की: [... this.state.myArray, 'नई वैल्यू'] अपने स्टेट व्यू को अपडेट करने के लिए। लेकिन क्या यह केवल अंतिम मान है। क्या आप मुझे समाधान बता सकते हैं?
जॉनसी

@ जॉनी मुझे यकीन नहीं है कि अगर आपका मुद्दा इस प्रश्न से संबंधित है, तो एक अलग प्रश्न पूछने और अपेक्षित व्यवहार का वर्णन करने की कोशिश करें और मैं आपकी मदद करने की कोशिश करूंगा।
अलीकसेंडर सुशेविच 17

5
प्रति प्रतिक्रिया डॉक्स के अनुसार: "क्योंकि this.propsऔर this.stateअतुल्यकालिक रूप से अपडेट किया जा सकता है, आपको अगले राज्य की गणना के लिए उनके मूल्यों पर भरोसा नहीं करना चाहिए।" एक सरणी को संशोधित करने के मामले में, चूंकि सरणी पहले से ही एक संपत्ति के रूप में मौजूद है this.stateऔर आपको एक नया मान सेट करने के लिए इसके मूल्य को संदर्भित करने की आवश्यकता है, आपको setState()एक तर्क के रूप में पिछले राज्य के साथ एक फ़ंक्शन को स्वीकार करने के रूप में उपयोग करना चाहिए । उदाहरण: this.setState(prevState => ({ myArray: [...this.state.myArray, 'new value'] }));देखें: reactjs.org/docs/...
बंगल

104

राज्य को सीधे म्यूट करने की अनुशंसा कभी नहीं की गई।

बाद के रिएक्ट संस्करणों में अनुशंसित दृष्टिकोण रेस स्थितियों को रोकने के लिए राज्यों को संशोधित करते समय एक अपडेटर फ़ंक्शन का उपयोग करना है:

सरणी के अंत में स्ट्रिंग को पुश करें

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))

सरणी की शुरुआत करने के लिए स्ट्रिंग को पुश करें

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))

सरणी के अंत में ऑब्जेक्ट पुश करें

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))

सरणी की शुरुआत में ऑब्जेक्ट को पुश करें

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))

1
मैंने इस जवाब का इस्तेमाल किया। यह सरणी में बहाने के लिए भी काम करता है:this.setState((prevState) => ({ myArray: [values, ...prevState.myArray], }));
गस

1
यह स्वीकार किए गए उत्तर की तुलना में बहुत बेहतर दृष्टिकोण है और क्या यह उस तरह से करता है जिस तरह से प्रतिक्रिया प्रलेखन की सिफारिश करता है।
इयान जे मिलर

2
निश्चित रूप से + 1 इस पर क्योंकि अन्य उत्तर कॉलबैक का उपयोग करने के नवीनतम दिशानिर्देशों का पालन नहीं करते हैं यदि राज्य स्वयं के साथ उत्परिवर्तन करता है।
मैट फ्लेचर

कैसे राज्य सरणी में एक और सरणी वस्तुओं को जोड़ने के लिए?
चांदनी

14

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

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);

राज्य वस्तु पर सीधे काम करना वांछनीय नहीं है। आप रिएक्ट के अपरिवर्तनीय सहायकों पर भी नज़र डाल सकते हैं।

https://facebook.github.io/react/docs/update.html


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

11

आप .concatनए डेटा के साथ अपने एरे की कॉपी बनाने के लिए विधि का उपयोग कर सकते हैं :

this.setState({ myArray: this.state.myArray.concat('new value') })

लेकिन .concatसरणियों को पारित करते समय विधि के विशेष व्यवहार से सावधान रहें - [1, 2].concat(['foo', 3], 'bar')परिणाम होगा [1, 2, 'foo', 3, 'bar']


1

यह कोड मेरे लिए काम करता है:

fetch('http://localhost:8080')
  .then(response => response.json())
  .then(json => {
  this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})

3
ढेर अतिप्रवाह में आपका स्वागत है! कृपया स्रोत कोड के साथ जवाब न दें। आपका समाधान कैसे काम करता है, इसके बारे में अच्छा विवरण देने का प्रयास करें। देखें: मैं एक अच्छा उत्तर कैसे लिखूं? । धन्यवाद
s Sepunı

मैंने यह कोशिश की लेकिन कोई फायदा नहीं हुआ। यहाँ मेरा कोड हैfetch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value + KEY} `) .then( response => response.json() ) .then( data => { this.setState({ reports: this.state.reports.push.apply(this.state.reports, data.list)}); });
henrie

और मैं सबसे पहले एक खाली सरणी के रूप में इनिशियलाइज़्ड this.state = { reports=[] }
स्टेट्स

@ हामिद होसेनपौर
हेनरी जूल

1

प्रतिक्रिया-मूलनिवासी

अगर आप भी उर यूआई चाहते हैं (यानी उर फ्लैट लिस्ट) अप टू डेट, प्रीवस्टेट का उपयोग करें: नीचे दिए गए उदाहरण में यदि उपयोगकर्ता बटन पर क्लिक करता है, तो यह सूची में एक नया ऑब्जेक्ट जोड़ने जा रहा है (मॉडल और यूआई दोनों में) )

data: ['shopping','reading'] // declared in constructor
onPress={() => {this.setState((prevState, props) => {
return {data: [new obj].concat(prevState.data) };
})}}. 

0

निम्नलिखित तरीके से हम वस्तुओं की जाँच और अद्यतन कर सकते हैं

this.setState(prevState => ({
    Chart: this.state.Chart.length !== 0 ? [...prevState.Chart,data[data.length - 1]] : data
}));

0

यहां आप ऑब्जेक्ट को इस तरह राज्य सरणी में नहीं धकेल सकते हैं। आप सामान्य सरणी में अपने तरीके से धक्का दे सकते हैं। यहां आपको राज्य सेट करना होगा,

this.setState({ 
     myArray: [...this.state.myArray, 'new value'] 
})

-1

यदि आप केवल राज्य को अपडेट करने का प्रयास कर रहे हैं तो

   handleClick() {
        this.setState(
{myprop: this.state.myprop +1}
        })
    }

इस दृष्टिकोण पर विचार करें

   handleClick() {
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        })
    }

असल में prevState यह लिख रहा है। हमारे लिए।

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