javascript - tutorial - redux




React.js এ অ্যারে শিশুদের জন্য অনন্য কীগুলি বোঝা (5)

আপনার প্রতিটি বাচ্চার পাশাপাশি বাচ্চাদের ভিতরে থাকা প্রতিটি উপাদানকে একটি কী যুক্ত করা উচিত।

এইভাবে প্রতিক্রিয়া হ'ল নূন্যতম ডিওএম পরিবর্তনটি পরিচালনা করতে পারে।

আপনার কোডে, প্রতিটি <TableRowItem key={item.id} data={item} columns={columnNames}/> কোনও বাচ্চা ছাড়াই তাদের ভিতরে কিছু শিশুদের রেন্ডারে চেষ্টা করছে।

এই উদাহরণটি পরীক্ষা করুন।

ডিভের ভিতরে <b></b> উপাদান থেকে key={i} removing মুছে ফেলার চেষ্টা করুন (এবং কনসোলটি পরীক্ষা করুন)।

নমুনায়, আমরা যদি <b> উপাদানটির জন্য কোনও কী না দিয়ে থাকি এবং আমরা কেবলমাত্র object.city আপডেট করতে object.city , প্রতিক্রিয়াটির পুরো সারিটি কেবলমাত্র উপাদানটিকে পুনরায় সরবরাহ করতে হবে।

কোডটি এখানে:

var data = [{name:'Jhon', age:28, city:'HO'},
            {name:'Onhj', age:82, city:'HN'},
            {name:'Nohj', age:41, city:'IT'}
           ];

var Hello = React.createClass({

    render: function() {

      var _data = this.props.info;
      console.log(_data);
      return(
        <div>
            {_data.map(function(object, i){
               return <div className={"row"} key={i}> 
                          {[ object.name ,
                             // remove the key
                             <b className="fosfo" key={i}> {object.city} </b> , 
                             object.age
                          ]}
                      </div>; 
             })}
        </div>
       );
    }
});

React.render(<Hello info={data} />, document.body);

নীচে @Chris দ্বারা পোস্ট করা উত্তরটি এই উত্তরটির চেয়ে অনেক বেশি বিশদে চলে গেছে। দয়া করে https://stackoverflow.com/a/43892905/2325522 এ একবার দেখুন

পুনর্মিলন Keys গুরুত্ব সম্পর্কে ডকুমেন্টেশন প্রতিক্রিয়া: Keys

আমি একটি প্রতিক্রিয়া উপাদান তৈরি করছি যা একটি JSON ডেটা উত্স গ্রহণ করে এবং একটি সারণযোগ্য টেবিল তৈরি করে।
গতিশীল ডেটা সারিগুলির প্রত্যেকটির কাছে একটি স্বতন্ত্র কী বরাদ্দ করা হয়েছে তবে আমি এর ত্রুটি পেয়েছি:

অ্যারেতে প্রতিটি সন্তানের একটি অনন্য "কী" প্রপস থাকা উচিত।
টেবিল কম্পোনেন্টের রেন্ডার পদ্ধতিটি পরীক্ষা করুন।

আমার TableComponent রেন্ডার পদ্ধতির রিটার্ন দেয়:

<table>
  <thead key="thead">
    <TableHeader columns={columnNames}/>
  </thead>
  <tbody key="tbody">
    { rows }
  </tbody>
</table>

TableHeader উপাদানটি একটি একক সারি এবং TableHeader একটি অনন্য কী বরাদ্দ রয়েছে।

rows প্রতিটি row একটি অনন্য কী সহ একটি উপাদান থেকে নির্মিত:

<TableRowItem key={item.id} data={item} columns={columnNames}/>

এবং TableRowItem দেখাচ্ছে:

var TableRowItem = React.createClass({
  render: function() {

    var td = function() {
        return this.props.columns.map(function(c) {
          return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
        }, this);
      }.bind(this);

    return (
      <tr>{ td(this.props.item) }</tr>
    )
  }
});

কী অনন্য কী প্রপ ত্রুটি ঘটাচ্ছে?


আমি প্রতিটি কি-র জন্য এইভাবে গাইড ব্যবহার করে এটি স্থির করেছি: উত্পন্ন গাইড:

guid() {
    return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' +
        this.s4() + '-' + this.s4() + this.s4() + this.s4();
}

s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
}

এবং তারপরে চিহ্নিতকারীগুলিকে এই মানটি বরাদ্দ করুন:

{this.state.markers.map(marker => (
              <MapView.Marker
                  key={this.guid()}
                  coordinate={marker.coordinates}
                  title={marker.title}
              />
          ))}

কেবলমাত্র আপনার উপাদানগুলিতে অনন্য কী যুক্ত করুন

Each child in a list should have a unique "key" prop.

চেক করুন: কী = অপরিশোধিত !!!

আপনি সতর্ক বার্তাটি পেয়েছেন:

<ObjectRow key={someValue} />

যদি আপনার কোডটি সম্পূর্ণ সঠিক হয় তবে এটি যদি চালু থাকে

class UsersState extends Component
    {
        state = {
            users: [
                {name:"shashank", age:20},
                {name:"vardan", age:30},
                {name:"somya", age:40}
            ]
        }
    render()
        {
            return(
                    <div>
                        {
                            this.state.users.map((user, index)=>{
                                return <UserState key={index} age={user.age}>{user.name}</UserState>
                            })
                        }
                    </div>
                )
        }

কিছু মূল্য নির্ধারিত !!! প্রথমে এটি পরীক্ষা করে দেখুন। আপনি ঘন্টা বাঁচাতে পারেন।


অ্যারেগুলিতে পুনরাবৃত্তি করার সময় সাবধানতা অবলম্বন করুন !!

এটি একটি সাধারণ ভ্রান্ত ধারণা যে অ্যারেতে উপাদানটির সূচকটি ব্যবহার করা সম্ভবত আপনি যে ত্রুটিটির সাথে পরিচিত তা দমন করার একটি গ্রহণযোগ্য উপায়:

Each child in an array should have a unique "key" prop.

তবে অনেক ক্ষেত্রে তা হয় না! এটি প্যাটার্ন বিরোধী যা কিছু পরিস্থিতিতে অযাচিত আচরণের দিকে পরিচালিত করতে পারে


key প্রোপ বোঝা যাচ্ছে

প্রতিক্রিয়াটি কম্পোনেন্ট-টু-ডম উপাদান উপাদান বোঝার জন্য key প্রপ ব্যবহার করে, যা পরে পুনর্মিলন প্রক্রিয়াটির জন্য ব্যবহৃত হয়। সুতরাং এটি অত্যন্ত গুরুত্বপূর্ণ যে কীটি সর্বদা অনন্য থাকে, অন্যথায় একটি ভাল সুযোগ রয়েছে প্রতিক্রিয়াটি উপাদানগুলির সাথে মিশে যায় এবং ভুলটিকে রূপান্তরিত করে। সর্বোত্তম পারফরম্যান্স বজায় রাখার জন্য এই কীগুলি সমস্ত রি-রেন্ডারগুলিতে স্থির থাকে তাও গুরুত্বপূর্ণ।

যা বলা হচ্ছে, একজনকে সর্বদা উপরের প্রয়োগের প্রয়োজন হয় না তবে শর্ত থাকে যে অ্যারে সম্পূর্ণ স্থিতিশীল। যাইহোক, সেরা অভ্যাস প্রয়োগ যখনই সম্ভব উত্সাহিত করা হয়।

একজন প্রতিক্রিয়া বিকাশকারী github.com/facebook/react/issues/1342#issuecomment-39230939 :

  • কীটি প্রকৃতপক্ষে পারফরম্যান্সের বিষয়ে নয়, এটি পরিচয় সম্পর্কে আরও বেশি (যা আরও ভাল পারফরম্যান্সের দিকে নিয়ে যায়)। এলোমেলোভাবে নির্ধারিত এবং মানগুলি পরিবর্তন নয়
  • আপনার ডেটা কীভাবে মডেল করা হয়েছে তা না জেনে আমরা বাস্তবতার সাথে কীগুলি সরবরাহ করতে পারি না [স্বয়ংক্রিয়ভাবে]। আমি আপনাকে আইডি না থাকলে সম্ভবত কিছু ধরণের হ্যাশিং ফাংশন ব্যবহার করার পরামর্শ দেব
  • অ্যারে ব্যবহার করার সময় আমাদের কাছে ইতিমধ্যে অভ্যন্তরীণ কী রয়েছে তবে সেগুলি অ্যারের সূচক। আপনি যখন একটি নতুন উপাদান sertোকান, সেই কীগুলি ভুল।

সংক্ষেপে, একটি key হওয়া উচিত:

  • অনন্য - একটি কী কোনও ভাইবোনের অংশের সাথে অভিন্ন হতে পারে না।
  • স্ট্যাটিক - একটি কী কখনও রেন্ডারগুলির মধ্যে পরিবর্তন করা উচিত নয়।


key প্রপ ব্যবহার করা হচ্ছে

উপরের ব্যাখ্যা অনুসারে, সাবধানে নিম্নলিখিত নমুনাগুলি অধ্যয়ন করুন এবং সম্ভব হলে, প্রস্তাবিত পদ্ধতির প্রয়োগ করার চেষ্টা করুন।

খারাপ (সম্ভাব্য)

<tbody>
    {rows.map((row, i) => {
        return <ObjectRow key={i} />;
    })}
</tbody>

প্রতিক্রিয়াটিতে কোনও অ্যারের উপরে পুনরাবৃত্তি করার সময় এটি সবচেয়ে ত্রুটিপূর্ণভাবে দেখা যায় seen এই পদ্ধতিটি প্রযুক্তিগতভাবে "ভুল" নয় , আপনি কী করছেন তা যদি আপনি না জানেন তবে এটি ঠিক ... "বিপজ্জনক" । আপনি যদি কোনও স্ট্যাটিক অ্যারের মাধ্যমে পুনরাবৃত্তি করেন তবে এটি একটি সম্পূর্ণ বৈধ পন্থা (যেমন আপনার নেভিগেশন মেনুতে লিঙ্কগুলির একটি অ্যারে)। তবে, আপনি যদি আইটেমগুলি যোগ, অপসারণ, পুনরায় অর্ডারিং বা ফিল্টারিং করছেন তবে আপনার সতর্কতা অবলম্বন করা উচিত। অফিসিয়াল ডকুমেন্টেশনে এই বিস্তারিত ব্যাখ্যাটি একবার দেখুন।

class MyApp extends React.Component {
  constructor() {
    super();
    this.state = {
      arr: ["Item 1"]
    }
  }
  
  click = () => {
    this.setState({
      arr: ['Item ' + (this.state.arr.length+1)].concat(this.state.arr),
    });
  }
  
  render() {
    return(
      <div>
        <button onClick={this.click}>Add</button>
        <ul>
          {this.state.arr.map(
            (item, i) => <Item key={i} text={"Item " + i}>{item + " "}</Item>
          )}
        </ul>
      </div>
    );
  }
}

const Item = (props) => {
  return (
    <li>
      <label>{props.children}</label>
      <input value={props.text} />
    </li>
  );
}

ReactDOM.render(<MyApp />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

এই স্নিপেটে আমরা একটি স্ট্যাটাসহীন অ্যারে ব্যবহার করছি এবং আমরা এটিকে স্ট্যাক হিসাবে ব্যবহার করতে সীমাবদ্ধ করছি না। এটি একটি অনিরাপদ পদ্ধতি (আপনি কেন তা দেখতে পাবেন)। অ্যারের শুরুতে আমরা কীভাবে আইটেমগুলি যুক্ত করব তা নোট করুন (মূলত আনশিফ্ট), প্রতিটি <input> এর মান স্থানে থাকে। কেন? কারণ key প্রতিটি আইটেম স্বতন্ত্রভাবে সনাক্ত করে না।

অন্য কথায়, প্রথম Item 1 key={0} যখন আমরা দ্বিতীয় আইটেমটি যুক্ত করি, শীর্ষ আইটেমটি Item 2 হয় এবং দ্বিতীয় আইটেম হিসাবে Item 1 দ্বারা অনুসরণ করা হয়। তবে, এখন Item 1 key={1} এবং key={0} নয়। পরিবর্তে, Item 2 এখন key={0} !!

এরূপ হিসাবে, প্রতিক্রিয়া মনে করে <input> উপাদানগুলি পরিবর্তন হয়নি, কারণ কী 0 সহ Item সর্বদা শীর্ষে থাকে!

সুতরাং কেন এই পদ্ধতির শুধুমাত্র কখনও কখনও খারাপ হয়?

এই অ্যারেটি কেবল ঝুঁকিপূর্ণ যদি অ্যারেটি কোনওভাবে ফিল্টার করা, পুনরায় সাজানো বা আইটেমগুলি যুক্ত / সরানো হয়। যদি এটি সর্বদা স্থির থাকে, তবে এটি ব্যবহার করা পুরোপুরি নিরাপদ। উদাহরণস্বরূপ, ["Home", "Products", "Contact us"] মতো একটি নেভিগেশন মেনু নিরাপদে এই পদ্ধতির মাধ্যমে পুনরাবৃত্তি করা যেতে পারে কারণ আপনি সম্ভবত নতুন লিঙ্কগুলি যুক্ত করবেন না বা এগুলি পুনরায় সাজবেন না।

সংক্ষেপে, আপনি যখন নিরাপদে সূচকটি key হিসাবে ব্যবহার করতে পারেন তা এখানে:

  • অ্যারে স্থির এবং কখনও পরিবর্তন হবে না।
  • অ্যারে কখনও ফিল্টার হয় না (অ্যারের একটি উপসেট প্রদর্শন করুন)।
  • অ্যারে কখনই পুনরায় অর্ডার হয় না।
  • অ্যারেটি স্ট্যাক বা LIFO (সর্বশেষে, প্রথম আউট) হিসাবে ব্যবহৃত হয়। অন্য কথায়, যোগ করা কেবলমাত্র অ্যারের শেষে (অর্থাত্ ধাক্কা) দিয়ে করা যায় এবং কেবল সর্বশেষ আইটেমটি কখনই সরানো যায় (অর্থাত পপ)।

যদি আমরা পরিবর্তে উপরের স্নিপেটে যোগ করা আইটেমটিকে অ্যারের শেষের দিকে ঠেলা দিয়ে থাকি তবে প্রতিটি বিদ্যমান আইটেমের ক্রমটি সর্বদা সঠিক হত।

খুব খারাপ

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={Math.random()} />;
    })}
</tbody>

যদিও এই পদ্ধতিটি সম্ভবত কীগুলির স্বতন্ত্রতার গ্যারান্টি দিবে, এটি সর্বদা তালিকার প্রতিটি আইটেম পুনরায় রেন্ডার করতে প্রতিক্রিয়া জোর করবে, এমনকি এটির প্রয়োজন নেই। এটি খুব খারাপ সমাধান কারণ এটি কার্যক্ষমতাকে ব্যাপকভাবে প্রভাবিত করে। Math.random() একই সংখ্যার দু'বার একই সংখ্যায় উত্পাদন করে এমন ক্ষেত্রে কোনও মূল সংঘর্ষের সম্ভাবনা বাদ দিতে পারে না তা উল্লেখ করার দরকার নেই।

অস্থির কী (যেমন Math.random() দ্বারা উত্পাদিত) এর ফলে অনেকগুলি উপাদান দৃষ্টান্ত এবং ডোম নোডগুলি অযথা পুনরায় তৈরি করাতে পারে, যা শিশু উপাদানগুলিতে কর্মক্ষমতা হ্রাস এবং Math.random() পারে।

খুব ভালো

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={row.uniqueId} />;
    })}
</tbody>

এটি যুক্তিযুক্ত সেরা পদ্ধতির কারণ এটি এমন একটি সম্পত্তি ব্যবহার করে যা ডেটাসেটের প্রতিটি আইটেমের জন্য স্বতন্ত্র। উদাহরণস্বরূপ, যদি rows একটি ডাটাবেস থেকে আনা ডেটা থাকে, তবে কেউ টেবিলের প্রাথমিক কী ( যা সাধারণত একটি স্বতঃবৃদ্ধিযোগ্য নম্বর ) ব্যবহার করতে পারে।

কী বাছাই করার সর্বোত্তম উপায় হ'ল স্ট্রিং ব্যবহার করা যা তার ভাইবোনদের মধ্যে একটি তালিকা আইটেমটি অনন্যভাবে চিহ্নিত করে। প্রায়শই আপনি কী হিসাবে আপনার ডেটা থেকে আইডি ব্যবহার করবেন

ভাল

componentWillMount() {
  let rows = this.props.rows.map(item => { 
    return {uid: SomeLibrary.generateUniqueID(), value: item};
  });
}

...

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={row.uid} />;
    })}
</tbody>

এটিও একটি ভাল পদ্ধতির। যদি আপনার ডেটাসেটে কোনও ডেটা না থাকে যা স্বতন্ত্রতার গ্যারান্টি দেয় ( উদাহরণস্বরূপ স্বেচ্ছাসেবী সংখ্যার একটি অ্যারে ), তবে কী সংঘর্ষের সম্ভাবনা রয়েছে। এই জাতীয় ক্ষেত্রে, ডেটাসেটের প্রতিটি আইটেমটির উপরে পুনরাবৃত্তি করার আগে ম্যানুয়ালি একটি অনন্য শনাক্তকারী তৈরি করা ভাল। সাধারণত উপাদানটি মাউন্ট করার সময় বা যখন ডেটাসেটটি গ্রহণ করা হয় ( যেমন প্রপস থেকে বা একটি এসিঙ্ক এপিআই কল থেকে ), কেবল একবার এটি করার জন্য, এবং প্রতিটি সময় উপাদান পুনরায় রেন্ডার করে না। ইতিমধ্যে বেশ কয়েকটি গ্রন্থাগার রয়েছে যা আপনাকে এই জাতীয় কী সরবরাহ করতে পারে। এখানে একটি উদাহরণ: react-key-index






reactjs