ProgramingTip

경고 : 고유 한 배열 또는 반복기의 각 하위에는 한 "키"소품이 있어야합니다.

bestdevel 2020. 10. 25. 12:43
반응형

경고 : 고유 한 배열 또는 반복기의 각 하위에는 한 "키"소품이 있어야합니다. `ListView`의 방법 확인


내가 가진 응용 프로그램 내장 ReactNative를 모두 iOS 용 및 안드로이드 . 목록보기를 유효한 데이터 소스로 채울 때 화면 하단에 다음 경고가 인쇄됩니다.ListView

경고 : 고유 한 배열 또는 반복기의 각 하위에는 한 "키"소품이 있어야합니다. 의 방법을 확인하십시오 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}
            />

    );
}

내 DataSource는 다음과 같이 구성됩니다.

    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)
    });

그리고 ListView-Rows는 다음과 같이 사용됩니다.

        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>
        );

나에게 완전히 말도 안되는 것처럼 보이는 경고를 제외하고는 모든 것이 작동합니다.

내 "DetailItem"-클래스에 키 속성을 추가해도 문제가 해결되지 않습니다.

이것은 "cloneWithRows"의 결과로 ListView에 실제로 전달되는 것입니다.

_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: '' } ] },

하나의 키에서 볼 수있는 각 레코드는 키 속성이 있습니다. 경고가 여전히 존재합니다.


내가 했어 정확히 잠시 동안 지금 당신과 같은 문제를, 위의 제안 중 일부보고 후, 나는 마침내 문제를 해결했다.

(적어도 어쨌든 나를 위해) renderSeparator 메서드에서 반환하는 구성 요소에 키 ( 'key'라는 소품)를 제공해야합니다. 내 renderRow 또는 renderSectionHeader에 키를 추가해도 아무 작업도 수행되지 않는 renderSeparator에 키를 추가하면 경고가 사라집니다.

도움이되기를 바랍니다.


를 제공해야합니다 .

키 속성이있는 경우 ListView 행 에서이 작업을 수행하십시오.

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

선택되지 않은 경우 항목을 키로 추가해.

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

반복 횟수 (i)를 다음 key같이 사용할 수도 있습니다 .

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


다음에서 코드 변경 :

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>
    );
}

그런 다음 해결되었습니다.


목록의 루트 구성 요소에 소품 '키'를 추가합니다.

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

이 경고는 목록 항목에 키를 추가하지 않을 때 발생합니다.

키는 React가 어떤 항목이 변경, 추가 또는 제거하는 데 도움이됩니다. 요소에 둘 다 ID를 제공하는 배열해야하는 내부의 요소에 키를 제공합니다.

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

키를 선택하는 가장 좋은 방법은 형제 중에서 목록 항목을 고유하게 구매하는 것을 사용하는 것입니다. 대부분의 경우 데이터의 ID를 키로 사용합니다.

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

렌더링 된 항목에 대한 안정적인 ID가없는 경우 마지막 수단으로 항목 인덱스를 키로 사용할 수 있습니다.

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

renderSeparator Component에 속성을 추가하여 수정했습니다. 코드는 다음과 같습니다.

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

이 경고의 핵심 단어는 "고유"이며 sectionID + rowID는 ListView에서 고유 한 값을 반환합니다.


renderDetailItem 메서드에 다음 서명 이 있다고 가정합니다 .

(rowData, sectionID, rowID, highlightRow) 

이렇게 해보세요 ...

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

이 문제를 해결하는 데 사용한 특정 코드는 다음과 같습니다.

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

구분 기호에 대해서도 고유해야하는 키가 필요하기 때문에 특정 코드를 포함했습니다. 예를 들어 이것을 상수로 설정하면 비슷한 작업을 수행하면 키 재사용에 대한 또 다른 성가신 오류가 발생합니다. JSX를 모르는 경우 다양한 부분을 실행하기 위해 JS에 대한 콜백을 구성하는 것이 상당히 어려울 수 있습니다.

그리고 ListView에서 분명히 이것을 첨부하십시오.

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

저를이 길로 안내 해준 coldbuffet과 Nader Dabit에게 감사드립니다.


확인 : key = undef !!!

경고 메시지도 받았습니다.

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

코드가 완벽하다면

<MyComponent key={someValue} />

someValue가 정의되지 않았습니다 !!! 먼저 확인하십시오. 시간을 절약 할 수 있습니다.


두 조건이 모두 충족 된 것 같습니다. 아마도 핵심 ( 'contact')이 문제입니다.

 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') );
}

이것은 충분히 강조 할 수 없습니다.

키는 주변 배열의 컨텍스트에서만 의미가 있습니다.

"예를 들어 ListItem 구성 요소를 추출하는 경우 ListItem 자체의 <li> 요소가 아닌 배열의 <ListItem /> 요소에 키를 유지해야합니다." -https : //reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys


여기 내 이해를 바탕으로합니다. 도움이 되었기를 바랍니다. 뒤에있는 예제로 구성 요소 목록을 렌더링해야합니다. 각 구성 요소의 루트 태그에는 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>),
    ];
}

<Fade in>반응 애플리케이션에 요소를 사용하는 경우 key={}속성도 추가 하십시오. 그렇지 않으면 콘솔에 오류가 표시됩니다.

참고 URL : https://stackoverflow.com/questions/34576332/warning-each-child-in-an-array-or-iterator-should-have-a-unique-key-prop-che

반응형