সতর্কতা: একটি অ্যারে বা পুনরাবৃত্তকারী প্রতিটি শিশুর একটি অনন্য "কী" প্রপস থাকা উচিত। `তালিকাভিউ` রেন্ডার পদ্ধতিটি পরীক্ষা করুন`


102

আমি আইওএস এবং অ্যান্ড্রয়েড উভয়ের জন্য রিএকটিএটিভের সাথে একটি অ্যাপ তৈরি করেছি ListView। বৈধ ডেটাসোর্স দ্বারা তালিকার দর্শনটি পপুলেট করার সময়, নিম্নলিখিত সতর্কতাটি স্ক্রিনের নীচে মুদ্রিত হয়:

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

এই সতর্কতার উদ্দেশ্য কী? বার্তার পরে তারা এই পৃষ্ঠায় লিঙ্ক করে , যেখানে সম্পূর্ণ বিভিন্ন বিষয় নিয়ে আলোচনা করা হয়েছে যা দেশীয় প্রতিক্রিয়াটির সাথে কোনও সম্পর্ক নেই, তবে ওয়েব ভিত্তিক বিক্রিয়াগুলির সাথে।

আমার তালিকাভিউ সেই বিবৃতি দিয়ে নির্মিত:

render() {
    var store = this.props.store;

    return (

        <ListView
            dataSource={this.state.dataSource}
            renderHeader={this.renderHeader.bind(this)}
            renderRow={this.renderDetailItem.bind(this)}
            renderSeparator={this.renderSeparator.bind(this)}
            style={styles.listView}
            />

    );
}

আমার ডেটা সোর্স এ জাতীয় কিছু নিয়ে গঠিত:

    var detailItems = [];

    detailItems.push( new DetailItem('plain', store.address) );
    detailItems.push( new DetailItem('map', '') );

    if(store.telefon) {
        detailItems.push( new DetailItem('contact', store.telefon, 'Anrufen', 'fontawesome|phone') );
    }
    if(store.email) {
        detailItems.push( new DetailItem('contact', store.email, 'Email', 'fontawesome|envelope') );
    }
    detailItems.push( new DetailItem('moreInfo', '') );

    this.setState({
        dataSource: this.state.dataSource.cloneWithRows(detailItems)
    });

এবং তালিকাগুলি-সারিগুলিকে এই জাতীয় সামগ্রীর সাথে রেন্ডার করা হয়:

        return (
            <TouchableHighlight underlayColor='#dddddd'>
                <View style={styles.infoRow}>
                    <Icon
                                name={item.icon}
                                size={30}
                                color='gray'
                                style={styles.contactIcon}
                                />
                    <View style={{ flex: 1}}>
                        <Text style={styles.headline}>{item.headline}</Text>
                        <Text style={styles.details}>{item.text}</Text>
                    </View>
                    <View style={styles.separator}/>
                </View>
            </TouchableHighlight>
        );

আমার কাছে সম্পূর্ণ সতর্কবাণী বলে মনে হচ্ছে এমন সতর্কতা বাদে সবকিছু ঠিকঠাক এবং প্রত্যাশার মতো কাজ করে।

আমার "বিবরণ আইটেম" -ক্লাসে কী-সম্পত্তি যুক্ত করা সমস্যার সমাধান করেনি।

এটি হ'ল "ক্লোনওথরউজ" এর ফলস্বরূপ তালিকাভিউতে আসলে কী পাস হবে:

_dataBlob: 
I/ReactNativeJS( 1293):    { s1: 
I/ReactNativeJS( 1293):       [ { key: 2,
I/ReactNativeJS( 1293):           type: 'plain',
I/ReactNativeJS( 1293):           text: 'xxxxxxxxxx',
I/ReactNativeJS( 1293):           headline: '',
I/ReactNativeJS( 1293):           icon: '' },
I/ReactNativeJS( 1293):         { key: 3, type: 'map', text: '', headline: '', icon: '' },
I/ReactNativeJS( 1293):         { key: 4,
I/ReactNativeJS( 1293):           type: 'contact',
I/ReactNativeJS( 1293):           text: '(xxxx) yyyyyy',
I/ReactNativeJS( 1293):           headline: 'Anrufen',
I/ReactNativeJS( 1293):           icon: 'fontawesome|phone' },
I/ReactNativeJS( 1293):         { key: 5,
I/ReactNativeJS( 1293):           type: 'contact',
I/ReactNativeJS( 1293):           text: 'xxxxxxxxx@hotmail.com',
I/ReactNativeJS( 1293):           headline: 'Email',
I/ReactNativeJS( 1293):           icon: 'fontawesome|envelope' },
I/ReactNativeJS( 1293):         { key: 6, type: 'moreInfo', text: '', headline: '', icon: '' } ] },

একটি কী হিসাবে দেখুন, প্রতিটি রেকর্ডের একটি মূল সম্পত্তি রয়েছে। সতর্কতা এখনও বিদ্যমান।


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

"কী" দিয়ে আপনি কী বোঝাতে চাইছেন? একটি সম্পত্তি "কী" বলা হয়?
মুছুন


এটি সমাধান করে না। আমি আমার ডেটা কাঠামোতে একটি মূল সম্পত্তি যুক্ত করেছি এবং আরও বিশদযুক্ত ডেটা সহ মূল প্রশ্নটি আপডেট করেছি। প্লেইন ডেটা তালিকাবদ্ধ করা, যা ফলাফল ডেটা উত্সে আসে প্রতিটি রেকর্ডে একটি কী থাকে। এই সতর্কতা রয়ে গেছে।
মুছুন

এটি অন্যান্য রেন্ডার পদ্ধতিগুলি থেকেও আসতে পারে (রেন্ডারহাইডার, রেন্ডারডেটাইল আইটেম, রেন্ডারসেটর)
পিট টিএনটি

উত্তর:


93

আমি ঠিক ছিলআপনার কিছুক্ষণের জন্য একই সমস্যাটি এবং উপরের কয়েকটি পরামর্শ দেখার পরে অবশেষে আমি সমস্যার সমাধান করেছি।

এটি দেখা যাচ্ছে (কমপক্ষে আমার জন্য যাইহোক), আমার রেন্ডারসেপেটর পদ্ধতিটি থেকে যে উপাদানটি আমি ফিরে আসছি তার জন্য আমাকে একটি চাবি ('কী' বলে একটি প্রপ) সরবরাহ করতে হবে। আমার রেন্ডাররে বা রেন্ডারসেকশনহাইডারটিতে একটি কী যুক্ত করা কোনও কাজ করেনি, তবে এটি রেন্ডারসেপরেটারে যুক্ত করা সতর্কতাটি দূরে সরিয়ে দিয়েছে।

আশা করি এইটি কাজ করবে.


আমার ক্ষেত্রে, আমি সবেমাত্র রেন্ডারসেপেটরটিকে মুছে ফেলেছি এবং আমার <সেপারেটর> রেন্ডার-র রিটার্ন মানটির শরীরে স্থানান্তরিত করেছি।
নৌকা কোডার ২

এখানে একই জিনিস SectionList , আরএনকে খুশি করতে প্রত্যেকের জন্য নাম কী সহ একটি সম্পত্তি যুক্ত itemকরতে হবে।
লিওন - হান লি

4
এটি পড়ার আগে আমি আমার জেএসওএন ডেটাতে কি সমস্যা বলে মনে করেছি তা অনুসন্ধানের জন্য আমি প্রায় 8 ঘন্টা নষ্ট করেছি। যদি সেখানে কোনও স্ট্যাক ওভারফ্লো হয়: টাকো: আমি আপনাকে একটি উপহার দিয়েছি!
Hoekma

76

আপনাকে একটি কী সরবরাহ করতে হবে

আপনার যদি কোনও মূল সম্পত্তি থাকে তবে আপনার তালিকাভিউ সারিগুলিতে এটি করার চেষ্টা করুন:

<TouchableHighlight key={item.key} underlayColor='#dddddd'>

যদি তা না হয় তবে কেবল আইটেমটিকে কী হিসাবে যুক্ত করার চেষ্টা করুন:

<TouchableHighlight key={item} underlayColor='#dddddd'>

4
আমি এই উত্তরটি আরও পছন্দ করি, কারণ এটির কোড রয়েছে তাই আমি
এক্সডিটি

34

আপনি পুনরাবৃত্তি গণনা (i) হিসাবে এটি ব্যবহার করতে পারেন key:

render() {
    return (
      <ol>
        {this.props.results.map((result, i) => (
          <li key={i}>{result.text}</li>
        ))}
      </ol>
    );
}

4
অ্যারে পরিবর্তিত হলে এটি কাজ করতে পারে না। এই উত্তরটি এটি উদাহরণ দিয়ে ব্যাখ্যা করেছে: stackoverflow.com/a/43892905/960857
ক্রিস

21

থেকে আপনার কোড পরিবর্তন করুন:

render() {
    return (
      <ol>
        {this.props.results.map((result) => (
          <li>{result.text}</li>
        ))}
      </ol>
    );
}

প্রতি:

render() {
    return (
      <ol>
        {this.props.results.map((result) => (
          <li key={result.id}>{result.text}</li>
        ))}
      </ol>
    );
}

তারপরে সমাধান হয়েছে।


13

তালিকার রেন্ডারিং রুট উপাদানটিতে একটি প্রোপ 'কী' যুক্ত করুন।

<ScrollView>
      <List>
          {this.state.nationalities.map((prop, key) => {
             return (
               <ListItem key={key}>
                  <Text>{prop.name}</Text>
               </ListItem>
             );
          })}
      </List>
</ScrollView>

6

আপনি যখন আপনার তালিকার আইটেমগুলিতে কোনও কী যুক্ত করবেন না তখন এই সতর্কতাটি আসে j

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

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

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

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

যখন আপনার রেন্ডার আইটেমগুলির জন্য স্থিতিশীল আইডি না থাকে, আপনি আইটেম সূচকটিকে একটি শেষ অবলম্বন হিসাবে কী হিসাবে ব্যবহার করতে পারেন

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

4

আমি এটিকে সংশোধন করে একটি সম্পত্তি যুক্ত করে রেন্ডারসেপেটর কম্পোনেন্টে যুক্ত করব, কোডটি এখানে রয়েছে:

_renderSeparator(sectionID,rowID){
    return (
        <View style={styles.separatorLine} key={"sectionID_"+sectionID+"_rowID_"+rowID}></View>
    );
}

এই সতর্কতার মূল শব্দগুলি হ'ল "অনন্য", সেকশন আইডি + সার্কআইডিটি ভিভিউ তালিকায় একটি অনন্য মান দেয়।


4

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

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

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

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

<MyComponent key={someValue} />

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



3

আমি এটি নির্দিষ্ট করতে নির্দিষ্ট কোডটি ব্যবহার করেছি:

  renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
    return (
      <View style={styles.separator} key={`${sectionID}-${rowID}`}/>
    )
  }

আমি নির্দিষ্ট কোডটি অন্তর্ভুক্ত করছি কারণ আপনার কীগুলি অনন্য হতে প্রয়োজন - এমনকি বিভাজকগুলির জন্যও। আপনি যদি অনুরূপ কিছু করেন তবে, যদি আপনি এটি একটি ধ্রুবক হিসাবে সেট করেন তবে আপনি কীগুলির পুনরায় ব্যবহার সম্পর্কে আরও একটি বিরক্তিকর ত্রুটি পাবেন। আপনি যদি জেএসএক্স না জানেন, বিভিন্ন অংশ সম্পাদনের জন্য জেএসকে কলব্যাক তৈরি করা বেশ ব্যথা হতে পারে।

এবং তালিকাভিউতে স্পষ্টতই এটি সংযুক্ত করছে:

<ListView
  style={styles.listview}
  dataSource={this.state.dataSource}
  renderRow={this.renderRow.bind(this)}
  renderSeparator={this.renderSeparator.bind(this)}
  renderSectionHeader={this.renderSectionHeader.bind(this)}/>

কোল্ড বুফেট এবং নাদের ডাবিটকে কৃতিত্ব যিনি আমাকে এই পথটি দেখিয়েছেন।


2

এখানে আমার বোঝার উপর ভিত্তি করে। আশা করি এটি সহায়ক। এর পিছনের উদাহরণ হিসাবে কোনও উপাদানগুলির একটি তালিকা রেন্ডার করার কথা। প্রতিটি উপাদানগুলির মূল ট্যাগের একটি থাকা দরকার key। এটি অনন্য হতে হবে না। এটা হতে না পারেন, key=0, key='0', ইত্যাদি দেখে মনে হচ্ছে কী অনর্থক।

render() {
    return [
        (<div key={0}> div 0</div>),
        (<div key={1}> div 2</div>),
        (<table key={2}><tbody><tr><td> table </td></tr></tbody></table>),
        (<form key={3}> form </form>),
    ];
}

0

উভয় শর্ত পূরণ হয়েছে বলে মনে হচ্ছে, সম্ভবত কী ('পরিচিতি') সমস্যা

 if(store.telefon) {
    detailItems.push( new DetailItem('contact', store.telefon, 'Anrufen', 'fontawesome|phone') );
}
if(store.email) {
    detailItems.push( new DetailItem('contact', store.email, 'Email', 'fontawesome|envelope') );
}

না, যোগাযোগ কোনও কী নয়। এর মধ্যে আমি আমার ডেটা কাঠামোতে "কী" নামক একটি আসল সম্পত্তি যুক্ত করেছি এবং আরও বিস্তারিত তথ্য পাস করে আমার প্রশ্নকে আপডেট করেছি। কিছুই সাহায্য করে না। সতর্কতা রয়ে গেছে।
মুছুন

0

এই যথেষ্ট জোর করা যাবে না:

কীগুলি কেবল পার্শ্ববর্তী অ্যারের প্রসঙ্গে উপলব্ধি করে

"উদাহরণস্বরূপ, আপনি যদি একটি তালিকা আইটেম উপাদান বের করেন তবে আপনার তালিকায় থাকা <li> উপাদানটির পরিবর্তে অ্যারেতে <তালিকা আইটেম /> উপাদানগুলিতে কীটি রাখা উচিত" " - https://reactjs.org/docs/lists-and-keys.html#extracting-comp घटक-with - keys


0

এই সমস্যাটিতে আমাকে যে বিষয়টি ছড়িয়ে দিয়েছে তা হ'ল আমি ভেবেছিলাম যে জেএসএক্স উপাদানগুলির বিপরীত হিসাবে 'রিয়েল' বা ডোম এইচটিএমএল উপাদানগুলির মতো দেখতে কীটির প্রয়োজন হবে I

অবশ্যই প্রতিক্রিয়া সহ আমরা একটি ভার্চুয়াল ডোম নিয়ে কাজ করছি সুতরাং আমরা যে প্রতিক্রিয়াটি জেএসএক্স উপাদানগুলি সংজ্ঞায়িত করি <MyElement>ঠিক ততটাই গুরুত্বপূর্ণ যেমন ডিওএমএল এইচটিএমএল উপাদানগুলির মতো দেখায় <div>

যে জানার জন্য?


0

আমার ক্ষেত্রে, আমি সিমেন্টিক ইউআই প্রতিক্রিয়া "কার্ড" ভিউটি ব্যবহার করছিলাম। আমি নিজের নির্মিত প্রতিটি কার্ডে একবার কী যুক্ত করলে সতর্কতাটি চলে গেল, উদাহরণস্বরূপ:

return (
        <Card fluid key={'message-results-card'}>
          ...
        </Card>
)

-1

আপনি যদি <Fade in>প্রতিক্রিয়ার অ্যাপ্লিকেশনটির জন্য উপাদানটি ব্যবহার করছেন তবে দয়া করে এটিতেও key={}বৈশিষ্ট্য যুক্ত করুন বা আপনি কনসোলে একটি ত্রুটি দেখতে পাবেন।

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