একটি প্রতিক্রিয়া অবস্থা পরিবর্তন করার জন্য পছন্দসই উপায় কী?


97

ধরা যাক আমার কাছে সরল বস্তুর একটি তালিকা রয়েছে this.state.listযা আমি তারপরে বাচ্চাদের একটি তালিকা রেন্ডার করতে ব্যবহার করতে পারি। এরপরে অবজেক্টটি toোকানোর সঠিক উপায় কী this.state.list?

নীচে কেবলমাত্র মনে হয় এটি কাজ করবে কারণ আপনি this.stateডকটিতে উল্লিখিত হিসাবে সরাসরি পরিবর্তন করতে পারবেন না ।

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

এটা আমার কাছে কুরুচিপূর্ণ মনে হয়। একটি ভাল উপায় আছে কি?



এই সমস্ত উত্তরগুলি অ্যারেতে একটি উপাদান যুক্ত করার বিষয়ে। কিন্তু এটি থেকে একটি উপাদান অপসারণ সম্পর্কে কি? বা কেবল নতুনটিকে অ্যারেটি পুনরায় সেট করতে?
অগস্টিন রিডিংগার

উত্তর:


164

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])
সোফি আল্পার্ট

@ বেনআল্পার্ট ক্রোমে আমার জন্য কাজ করে, আপনি কি বলছেন এটি মানহীন আচরণ?
গাদা

6
@ হিপ ওয়েল, আপনি যদি এটিতে একটি অ-অ্যারে পাস করেন concatতবে এটিকে একটি অ্যারেতে আবৃত করবে, তবে নিজেকে সুস্পষ্ট হতে অ্যারে যুক্ত করা ভাল: যদি আপনি পরবর্তী উপাদান হিসাবে [[1,2], [3,4]]যোগ করতে চান এবং [5,6]আপনাকে .concat([[5,6]])অন্য কিছু করতে হবে সাথে শেষ করব [[1,2], [3,4], 5, 6]
সোফি আল্পার্ট

4
অপরিবর্তনশীলতা সহায়কদের পিছনে যে ধারণাটি আমি প্রশংসা করি (এবং আমি যেভাবেই এটি ব্যবহার করে শেষ করতে পারি), Array.concatনিশ্চিতভাবেই অন্য একটি লাইব্রেরি যুক্ত করা যায়।
শান এরউখার্ট

4
এই.সেটস্টেট থেকে প্রাপ্ত মানটির সাথে এই.সেটস্টেট কল করা আপনার আপডেট ব্যাচিংয়ের সমস্যাগুলিকে খারাপ বলে মনে করবে। দেখুন stackoverflow.com/a/41445812/1998186 যা সমস্যা আপনি পাবেন দেখানোর সময় একটি jsfiddle লিঙ্ক।
NealeU

40

পরামিতি হিসাবে ফাংশন সহ সেটস্টেট () বলা যেতে পারে:

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

বা ES5 এ:

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

4
@ আরিয়ান: প্রতিক্রিয়া কেবলমাত্র নতুন যুক্ত হওয়া উপাদানগুলি রেন্ডার করতে প্রয়োজনীয় ডিওএম রূপান্তর নির্দেশাবলী সরিয়ে ফেলবে। অবশ্যই দেওয়া হয়েছে যে আপনি নতুন যুক্ত হওয়া উপাদানগুলি পূর্ববর্তী উপাদানগুলি কীভাবে রেন্ডার করে তা পরিবর্তন করে না।
হোসে ব্রাউন

4
এটি একটি চমত্কার উত্তর এবং এটি কেবল ধাক্কা দেওয়ার জন্য অ্যারে কনকাটেটিংয়ের চেয়ে অনেক বেশি পরিচ্ছন্ন বোধ করে, যদিও আমার ধারণা এই মতামত।
ম্যাট স্টাইলগুলি

4
@ নায়লাবকে কি আপনার প্যারেন্সেসিসে ফাংশন বডি মোড়ানো উচিত নয়? এটি যেমন এখন আপনার উদাহরণে দাঁড়িয়ে আছে, চর্বিযুক্ত তীরগুলির পরে বন্ধনীগুলি কোনও অবজেক্ট নয়, একটি ব্লক শুরু করবে। এরকম কিছু:this.setState((state) => ({ list: state.list.push(newObj) }))
কুমারহর্স

4
এই কোডটি কীভাবে কাজ করছে? পুশ পদ্ধতিটি ফিরে আসবে NUMBER, যা listভেরিয়েবলের উপর সেট করা হবে
কুমারহর্ষস

4
আপনি একটি স্প্ল্যাটও ব্যবহার করতে পারেন:this.setState((state) => ({ list: [...state.list, newObj] }))
অ্যামিবি

19

২০১ Update আপডেট করুন

ES6 এর সাহায্যে আপনি ব্যবহার করতে পারেন:

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

5
...[newObject]ঠিক হিসাবে একই newObject
অ্যামিবে

4
এটি বাচানো আপডেটের জন্য কাজ করবে না। আমার উদাহরণটি স্ট্যাকওভারফ্লো . com/a/41445812/1998186 এ দেখুন ।
NealeU

7

প্রতিক্রিয়া দস্তাবেজগুলি থেকে ( https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous ):

কারণ এই.পৃষ্ঠা এবং এটি.সেটটি অবিচ্ছিন্নভাবে আপডেট করা হতে পারে, আপনার পরবর্তী অবস্থার গণনার জন্য তাদের মানগুলিতে নির্ভর করা উচিত নয়।

পরিবর্তে আপনার এটি করা উচিত:

this.setState((prevState) => ({
  contacts: prevState.contacts.concat([contact])
}));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.