प्रतिक्रिया अवस्था को बदलने का पसंदीदा तरीका क्या है?


97

मान लीजिए कि मेरे पास सादे वस्तुओं की एक सूची है this.state.listजिसे मैं फिर बच्चों की सूची प्रदान करने के लिए उपयोग कर सकता हूं। तब वस्तु डालने का सही तरीका क्या है this.state.list?

नीचे एक ही तरीका है जो मुझे लगता है कि यह काम करेगा क्योंकि आप this.stateसीधे डॉक्टर के रूप में उल्लिखित नहीं कर सकते हैं ।

this._list.push(newObject):
this.setState({list: this._list});

यह मुझे बदसूरत लगता है। क्या कोई बेहतर तरीका है?


ReactJS में राज्य सरणियों के सही संशोधन का संभावित डुप्लिकेट , मर्ज करने का अनुरोध
Brigand

वे सभी उत्तर एक तत्व को एक सरणी में जोड़ने के बारे में हैं। लेकिन इसमें से एक तत्व को हटाने के बारे में क्या? या बस पूरी तरह से एक नया करने के लिए सरणी रीसेट करने के लिए?
ऑगस्टिन रीडिंगर

जवाबों:


165

concat एक नया सरणी देता है, ताकि आप कर सकें

this.setState({list: this.state.list.concat([newObject])});

एक अन्य विकल्प रिएक्ट की अपरिवर्तनीय सहायक है

  var newState = React.addons.update(this.state, {
      list : {
        $push : [newObject]
      }
  });

  this.setState(newState);

6
concatएक सरणी लेता है, इसलिए आप चाहते हैं this.state.list.concat([newObject])
सोफी एल्पर्ट

क्रोम में मेरे लिए @BenAlpert काम करता है, क्या आप कह रहे हैं कि यह गैर-मानक व्यवहार है?
ढेर

6
@Heap ठीक है, अगर तुम पारित करने के लिए एक गैर सरणी concatयह एक सरणी में लपेट होगा, लेकिन यह सरणी खुद को जोड़ने के लिए स्पष्ट होना बेहतर है: यदि आपके पास [[1,2], [3,4]]और जोड़ना चाहते हैं [5,6]अगले तत्व के रूप में, आप क्या करने की जरूरत .concat([[5,6]])आप और 'के साथ समाप्त होगा [[1,2], [3,4], 5, 6]
सोफी अल्परट

2
जितना मैं अपरिवर्तनीय सहायकों के पीछे के विचार की सराहना करता हूं (और मैं इसे वैसे भी उपयोग कर सकता हूं), Array.concatनिश्चित रूप से एक और पुस्तकालय जोड़कर धड़कता है।
शॉन एर्खर्ट

1
इस.state को इस मूल्य से प्राप्त करने के साथ कॉल करें। इससे आपको अपडेट बैचिंग समस्याओं से छुटकारा मिलेगा। देखें stackoverflow.com/a/41445812/1998186 जो आपको मिल रही समस्या को दिखाते हुए jsfiddle से लिंक करता है।
नेअलेउ

40

setState () को एक फंक्शन के साथ एक पैरामीटर के रूप में बुलाया जा सकता है:

this.setState((state) => ({ list: state.list.concat(newObj) }))

या ES5 में:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})

2
@ एरियन: रिएक्ट केवल नए जोड़े गए तत्वों को प्रस्तुत करने के लिए आवश्यक डोम उत्परिवर्तन निर्देशों को बाहर निकाल देगा। यह देखते हुए कि आप नए जोड़े गए तत्व नहीं हैं, पिछले तत्वों को कैसे बदला गया है।
जोस ब्राउन ने

1
यह एक शानदार जवाब है और सिर्फ एक धक्का देने के लिए समवर्ती सरणी की तुलना में बहुत अधिक क्लीनर लगता है, हालांकि मुझे लगता है कि विचार।
मैट स्टाइल्स

2
@ नियाल्ब क्या आपको फंक्शन बॉडी को कोष्ठक में नहीं लपेटना चाहिए? जैसा कि यह आपके उदाहरण में अभी खड़ा है, वसा तीर के बाद ब्रेस एक ब्लॉक शुरू होगा, एक वस्तु नहीं। कुछ इस तरह से:this.setState((state) => ({ list: state.list.push(newObj) }))
कुमारहर्ष

3
यह कोड कैसे काम कर रहा है? पुश विधि एक NUMBERlist
लौटाएगी

1
आप एक this.setState((state) => ({ list: [...state.list, newObj] }))
फव्वारे

19

अपडेट २०१६

ES6 के साथ आप उपयोग कर सकते हैं:

this.setState({ list: [...this.state.list, ...newObject] });

5
...[newObject]बस के रूप में ही है newObject
एमोबे

2
यह बैच अपडेट के लिए काम नहीं करेगा। पर मेरे उदाहरण देखें stackoverflow.com/a/41445812/1998186
नेयलेउ

7

प्रतिक्रिया डॉक्स ( https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous ) से:

क्योंकि यह.प्रॉप्स और इस.स्टेट को अतुल्यकालिक रूप से अपडेट किया जा सकता है, आपको अगले राज्य की गणना के लिए उनके मूल्यों पर भरोसा नहीं करना चाहिए।

इसलिए आपको इसके बजाय यह करना चाहिए:

this.setState((prevState) => ({
  contacts: prevState.contacts.concat([contact])
}));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.