ReactJS এ রাজ্য অ্যারেগুলির সঠিক পরিবর্তন mod


416

আমি stateঅ্যারের শেষে একটি উপাদান যুক্ত করতে চাই , এটি কি এটি সঠিক উপায়?

this.state.arrayvar.push(newelement);
this.setState({arrayvar:this.state.arrayvar});

আমি উদ্বিগ্ন যে জায়গায় জায়গায় অ্যারে সংশোধন করা সমস্যার pushকারণ হতে পারে - এটি নিরাপদ?

অ্যারের একটি অনুলিপি তৈরি করার বিকল্প, এবং setStateএটি যে অপব্যয় বলে মনে হচ্ছে ing


9
আমি মনে করি আপনি প্রতিক্রিয়াশীল অপরিবর্তনীয় সহায়কদের ব্যবহার করতে পারেন। এটি দেখুন: ফেসবুক.
github.io/react/docs/update.html#simple-push

রাষ্ট্র অ্যারের মধ্যে setState আমার সমাধান পরীক্ষা <br/> <br>। stackoverflow.com/a/59711447/9762736
Rajnikant লোদী

উত্তর:


763

প্রতিক্রিয়া ডক্স বলেছেন:

এটিকে স্টেট করুন as

আপনার pushরাজ্যটিকে সরাসরি রূপান্তরিত করবে এবং এর পরে আপনি রাষ্ট্রটিকে আবার "রিসেট" করে নিলেও তা ত্রুটিযুক্ত প্রবণ কোডের দিকে পরিচালিত করতে পারে। F.ex, এটি হতে পারে যে কিছু লাইফসাইकल পদ্ধতিগুলি componentDidUpdateট্রিগার করবে না।

পরবর্তী প্রতিক্রিয়া সংস্করণগুলিতে প্রস্তাবিত পদ্ধতির প্রতিযোগিতামূলক পরিস্থিতি প্রতিরোধের জন্য রাজ্যগুলিকে সংশোধন করার সময় আপডেটের ফাংশনটি ব্যবহার করা হয় :

this.setState(prevState => ({
  arrayvar: [...prevState.arrayvar, newelement]
}))

অ-মানক রাষ্ট্রীয় পরিবর্তন ব্যবহার করে আপনি যে ত্রুটিগুলির মুখোমুখি হতে পারেন তার তুলনায় মেমরি "বর্জ্য" কোনও সমস্যা নয়।

পূর্ববর্তী প্রতিক্রিয়া সংস্করণগুলির জন্য বিকল্প সিনট্যাক্স

আপনি concatএকটি ক্লিন সিনট্যাক্স পেতে ব্যবহার করতে পারেন যেহেতু এটি একটি নতুন অ্যারে দেয়:

this.setState({ 
  arrayvar: this.state.arrayvar.concat([newelement])
})

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

this.setState({
  arrayvar: [...this.state.arrayvar, newelement]
})

8
আপনি যখন একটি দৌড় অবস্থা হতে পারে একটি উদাহরণ প্রদান করতে পারেন?
11:12

3
@ কিমিং pushনতুন অ্যারের দৈর্ঘ্যটি প্রদান করে যাতে এটি কাজ করে না। এছাড়াও, setStateঅ্যাসিঙ্ক হয় এবং প্রতিক্রিয়া একক রেন্ডার পাসে বেশ কয়েকটি রাষ্ট্রীয় পরিবর্তনকে সারি করতে পারে।
ডেভিড হেলসিং

2
@ মাইন্ডেভোয়ার বলছেন আপনার কাছে একটি অ্যানিমেশন ফ্রেম রয়েছে যা এই.স্টেটের পরামিতিগুলির সন্ধান করে এবং অন্য একটি পদ্ধতি যা রাষ্ট্রের পরিবর্তনে কিছু অন্যান্য পরামিতি পরিবর্তন করে। কিছু ফ্রেম থাকতে পারে যেখানে রাষ্ট্র পরিবর্তিত হয়েছে তবে পরিবর্তনের জন্য শোনার পদ্ধতিতে প্রতিফলিত হয় না কারণ সেটস্টেট অ্যাসিঙ্ক।
ডেভিড হেলসিং

1
@ ক্রিস্টোফার ক্যাম্পস এই উত্তরটি setStateদু'বার কল করতে উত্সাহ দেয় না , এটি সরাসরি পরিবর্তন না করে রাষ্ট্র অ্যারে স্থাপনের অনুরূপ দুটি উদাহরণ দেখায়।
ডেভিড হেলসিং

2
এই দিনগুলিতে কোনও রাজ্য অ্যারেরকে অপরিবর্তনীয় হিসাবে আচরণ করার একটি সহজ উপায় হ'ল: let list = Array.from(this.state.list); list.push('woo'); this.setState({list});অবশ্যই আপনার স্টাইলের পছন্দগুলিতে পরিবর্তন করুন।
বেসডেডস

133

সবচেয়ে সহজ, আপনি যদি ব্যবহার করছেন ES6

initialArray = [1, 2, 3];

newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]

নতুন অ্যারে হবে [1,2,3,4]

প্রতিক্রিয়া আপনার রাষ্ট্র আপডেট করতে

this.setState({
         arrayvar:[...this.state.arrayvar, newelement]
       });

অ্যারে ডেস্ট্রাকচারিং সম্পর্কে আরও জানুন


@ মুজিওতো আপনি কি বিস্তারিত বলতে পারবেন?
স্টেটলাস

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

2
আপনার প্রশ্নগুলি সরাসরি ওপি প্রশ্নের সাথে সম্পর্কিত নয়
স্টেটলাস

1
@ChanceSmith: এটা প্রয়োজন হয় আড়ম্বরহীন উত্তর খুব। রাজ্য নিজেই রাজ্যের আপডেটের উপর নির্ভর করবেন না। অফিসিয়াল ডক: reactjs.org/docs/…
আরকোল

1
@ রায়কডার লগ করুন এবং অ্যারেভারের মানটি পরীক্ষা করুন, দেখে মনে হচ্ছে এটি অ্যারে নয়।
স্টেটলেস

57

এর সাথে সহজতম উপায় ES6:

this.setState(prevState => ({
    array: [...prevState.array, newElement]
}))

দুঃখিত, আমার ক্ষেত্রে আমি একটি অ্যারেটিকে অ্যারেতে ঠেকাতে চাই। tableData = [['test','test']]আমার নতুন অ্যারে ধাক্কা পরে tableData = [['test','test'],['new','new']]। এই @ ডেভিড এবং @ রিডকে কীভাবে ঠেলাবেন
জেন্সি

@ জোহেন্সি যদি আপনি [['test','test'],['new','new']]চেষ্টা করতে চান :this.setState({ tableData: [...this.state.tableData, ['new', 'new']]
রিড করুন

this.setState({ tableData: [...this.state.tableData ,[item.student_name,item.homework_status_name,item.comments===null?'-':item.comments] ] });এটি দু'বার নতুন অ্যারে সন্নিবেশ করায় এটি this.state.tableData.push([item.student_name,item.homework_status_name,item.comments===null?'-':item.comments]);আমার পছন্দসই জিনিস অর্জন করে। তবে এটি আমার সঠিক ধারণা নয়।
জেন্সি

26

প্রতিক্রিয়া ব্যাচের আপডেট হতে পারে, এবং তাই সঠিক পদ্ধতির আপডেটটি সম্পাদন করে এমন কোনও ফাংশন সহ সেটস্টেট সরবরাহ করা।

প্রতিক্রিয়া আপডেট অ্যাডনের জন্য, নিম্নলিখিতগুলি নির্ভরযোগ্যভাবে কাজ করবে:

this.setState( state => update(state, {array: {$push: [4]}}) );

বা কনক্যাট () এর জন্য:

this.setState( state => ({
    array: state.array.concat([4])
}));

নিম্নলিখিতটি আপনাকে https://jsbin.com/mofekakuqi/7/edit?js,output এর উদাহরণ হিসাবে দেখায় যে আপনি যদি ভুল হয়ে থাকেন তবে কী ঘটে।

সেটটাইমআউট () অনুরোধটি সঠিকভাবে তিনটি আইটেম যুক্ত করে কারণ প্রতিক্রিয়া কোনও সেটটাইমআউট কলব্যাকের মধ্যে আপডেটগুলি ব্যাচ করবে না ( https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ দেখুন )।

বাগি অনক্লিক কেবল "তৃতীয়" যুক্ত করবে, তবে স্থির একটিটি প্রত্যাশার সাথে সাথে এফ, এস এবং টি যুক্ত করবে।

class List extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      array: []
    }

    setTimeout(this.addSome, 500);
  }

  addSome = () => {
      this.setState(
        update(this.state, {array: {$push: ["First"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Second"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Third"]}}));
    };

  addSomeFixed = () => {
      this.setState( state => 
        update(state, {array: {$push: ["F"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["S"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["T"]}}));
    };



  render() {

    const list = this.state.array.map((item, i) => {
      return <li key={i}>{item}</li>
    });
       console.log(this.state);

    return (
      <div className='list'>
        <button onClick={this.addSome}>add three</button>
        <button onClick={this.addSomeFixed}>add three (fixed)</button>
        <ul>
        {list}
        </ul>
      </div>
    );
  }
};


ReactDOM.render(<List />, document.getElementById('app'));

সত্যিই এমন ঘটনা ঘটে যা ঘটে? আমরা যদি সহজভাবে করিthis.setState( update(this.state, {array: {$push: ["First", "Second", "Third"]}}) )
Albizia

1
@ আলবিজিয়া আমার মনে হয় আপনার কোনও সহকর্মী খুঁজে পাওয়া উচিত এবং তাদের সাথে এটি নিয়ে আলোচনা করা উচিত। আপনি যদি কেবল একটি সেটস্টেট কল করে থাকেন তবে কোনও ব্যাচিংয়ের সমস্যা নেই। পয়েন্টটি দেখানো হচ্ছে যে প্রতিক্রিয়া ব্যাচ আপডেটগুলি দেয়, তাই হ্যাঁ ... সত্যিই একটি কেস রয়েছে, যা আপনি উপরের কোডটির জেএসবিন সংস্করণে খুঁজে পেতে পারেন। এই থ্রেডের প্রায় সমস্ত উত্তরই এটিকে সম্বোধন করতে ব্যর্থ হয়, সুতরাং সেখানে প্রচুর কোড উপস্থিত হবে যা কখনও কখনও ভুল হয়ে যায়
NealeU

state.array = state.array.concat([4])এটি পূর্ববর্তী রাষ্ট্রের বস্তুকে রূপান্তরিত করে।
এমিল বার্গারন

1
@ এমিলিবার্গারন আপনার অধ্যবসায়ের জন্য আপনাকে ধন্যবাদ। আমি অবশেষে পিছনে ফিরে তাকালাম এবং দেখলাম আমার মস্তিষ্ক যা দেখতে অস্বীকার করছে, এবং ডক্সটি পরীক্ষা করেছে তাই আমি সম্পাদনা করব।
NealeU

1
ভাল! জেএসে অপরিবর্তনীয়তা অ-সুস্পষ্ট হওয়ায় এটি ভুল হওয়া সত্যিই সহজ (এমনকি আরও একটি লাইব্রেরির এপিআইয়ের সাথে কথা বলার সময়)।
এমিল বার্গারন

17

@ নীলগুন মন্তব্যে উল্লিখিত হিসাবে, আপনি প্রতিক্রিয়াশীল অপরিবর্তনশীলতা সহায়কদের ব্যবহার করতে পারেন । আমি এটি অত্যন্ত দরকারী বলে মনে করেছি।

দস্তাবেজগুলি থেকে:

সাধারণ ধাক্কা

var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

প্রারম্ভিক অ্যারে এখনও [1, 2, 3]।


6
প্রতিক্রিয়া অপরিবর্তনীয় সাহায্যকারীদের ডকুমেন্টেশনে অবচয় হিসাবে বর্ণনা করা হয়েছে। github.com/kolodny/immutability- সহায়তা এখন পরিবর্তে ব্যবহার করা উচিত।
পেরিটা ব্রেটা

3

আপনি যদি কার্যকরী উপাদান ব্যবহার করছেন তবে দয়া করে নীচের মত এটি ব্যবহার করুন।

const [chatHistory, setChatHistory] = useState([]); // define the state

const chatHistoryList = [...chatHistory, {'from':'me', 'message':e.target.value}]; // new array need to update
setChatHistory(chatHistoryList); // update the state

1

অ্যারেতে যুক্ত নতুন উপাদানগুলির জন্য, push()উত্তরটি হওয়া উচিত।

অ্যারের উপাদান এবং আপডেটের স্থিতি সরানোর জন্য, নীচের কোডটি আমার পক্ষে কাজ করে। splice(index, 1)কাজ করতে পারে না।

const [arrayState, setArrayState] = React.useState<any[]>([]);
...

// index is the index for the element you want to remove
const newArrayState = arrayState.filter((value, theIndex) => {return index !== theIndex});
setArrayState(newArrayState);

0

আমি একটি অ্যারে অবস্থায় মানকে ধাক্কা দেওয়ার চেষ্টা করছি এবং মানটির মতো করে সেট করবো এবং মানচিত্রের ফাংশন অনুসারে রাষ্ট্রের অ্যারের সংজ্ঞা দিন এবং মান ধাক্কা দেবো।

 this.state = {
        createJob: [],
        totalAmount:Number=0
    }


 your_API_JSON_Array.map((_) => {
                this.setState({totalAmount:this.state.totalAmount += _.your_API_JSON.price})
                this.state.createJob.push({ id: _._id, price: _.your_API_JSON.price })
                return this.setState({createJob: this.state.createJob})
            })

0

এটি আমার জন্য একটি অ্যারের মধ্যে একটি অ্যারে যুক্ত করার জন্য কাজ করেছিল

this.setState(prevState => ({
    component: prevState.component.concat(new Array(['new', 'new']))
}));

0

এখানে একটি ২০২০, র্যাকটজস হুক উদাহরণ যা আমি ভেবেছিলাম অন্যকে সাহায্য করতে পারে। আমি এটি একটি রিএ্যাকটিজস টেবিলটিতে নতুন সারি যুক্ত করতে ব্যবহার করছি। যদি আমি কোনও কিছুর উন্নতি করতে পারি তবে আমাকে জানান।

কার্যক্ষম রাষ্ট্রের উপাদানটিতে একটি নতুন উপাদান যুক্ত করা:

রাষ্ট্রের ডেটা সংজ্ঞায়িত করুন:

    const [data, setData] = useState([
        { id: 1, name: 'John', age: 16 },
        { id: 2, name: 'Jane', age: 22 },
        { id: 3, name: 'Josh', age: 21 }
    ]);

একটি নতুন উপাদান যুক্ত করতে একটি ফাংশন ট্রিগার করুন একটি বোতাম

<Button
    // pass the current state data to the handleAdd function so we can append to it.
    onClick={() => handleAdd(data)}>
    Add a row
</Button>
function handleAdd(currentData) {

        // return last data array element
        let lastDataObject = currentTableData[currentTableData.length - 1]

        // assign last elements ID to a variable.
        let lastID = Object.values(lastDataObject)[0] 

        // build a new element with a new ID based off the last element in the array
        let newDataElement = {
            id: lastID + 1,
            name: 'Jill',
            age: 55,
        }

        // build a new state object 
        const newStateData = [...currentData, newDataElement ]

        // update the state
        setData(newStateData);

        // print newly updated state
        for (const element of newStateData) {
            console.log('New Data: ' + Object.values(element).join(', '))
        }

}

-1
this.setState({
  arrayvar: [...this.state.arrayvar, ...newelement]
})

2
এটিকে নিম্নমানের পোস্ট হিসাবে বিবেচনা করতে এই পোস্টটি এড়াতে কিছু ব্যাখ্যা যুক্ত করুন stackoverflow
হর্ষ বিয়ানি

2
@ কোবে এই কলটি ES6 এ "স্প্রেড অপারেটর" এবং অ্যারে 1 এ অ্যারে 2 আইটেম যুক্ত করুন।
ডাউনভোটের

@ এম সামিই ডাউনভোটগুলি এড়াতে আপনার পোস্টটি সম্পাদনা করতে হবে। এটি কেবলমাত্র একটি কোড স্নিপেট হিসাবে নিম্নমানের। এছাড়াও, আপডেটগুলি ব্যাচ করা যেতে পারে বলে এইভাবে রাষ্ট্রটি পরিবর্তন করা বিপজ্জনক, তাই পছন্দের setState(state => ({arrayvar: [...state.arrayvar, ...newelement]}) );
উপায়টি হ'ল

এবং newelementঅ্যারের মধ্যে অবজেক্ট ছড়িয়ে দেওয়া TypeErrorযাইহোক।
এমিল বার্গারন

-1
//------------------code is return in typescript 

const updateMyData1 = (rowIndex:any, columnId:any, value:any) => {

    setItems(old => old.map((row, index) => {
        if (index === rowIndex) {
        return Object.assign(Object.assign({}, old[rowIndex]), { [columnId]: value });
    }
    return row;
}));

-6

এই কোডটি আমার পক্ষে কাজ করে:

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

2
তবুও, আপনি সরাসরি রাষ্ট্র পরিবর্তন করুন
আসবার আলী

2
আর কোনও অ্যারে নয়, .pushকোনও সংখ্যার রিটার্ন দেয় বলে উপাদানটির অবস্থা সঠিকভাবে আপডেট করতে ব্যর্থ ।
এমিল বার্গারন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.