source

경고:어레이 또는 반복기 내의 각 자녀는 고유한 "키" 프로펠러를 가져야 합니다.ListView의 렌더 메서드를 확인합니다.

itover 2023. 3. 28. 21:40
반응형

경고:어레이 또는 반복기 내의 각 자녀는 고유한 "키" 프로펠러를 가져야 합니다.ListView의 렌더 메서드를 확인합니다.

iOS용과 안드로이드용 모두 ReactNative로 앱을 만들었습니다.리스트뷰를 유효한 데이터 소스로 채우면 화면 하단에 다음과 같은 경고가 표시됩니다.

또는 내의 각한 " 프로펠러를 가져야 .어레이 또는 반복기 내의 각 자녀는 고유한 "키" 프로펠러를 가져야 합니다.해 보세요.ListView.

이 경고의 목적은 무엇입니까?메시지 뒤에 이 페이지로 링크됩니다.여기서는 리액트 네이티브와는 관계없는 웹 기반 리액트와는 전혀 다른 사항에 대해 설명합니다.

My List View는 다음 문장으로 작성됩니다.

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}
            />

    );
}

My Data Source는 다음과 같은 요소로 구성됩니다.

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

모든 것이 잘 되고 예상대로 잘 되고 있다. 다만 나에게는 전혀 말이 안 되는 것 같은 경고만 빼면 말이다.

"Detail Item" 클래스에 키 속성을 추가해도 문제가 해결되지 않았습니다.

다음은 "Clone With Rows"의 결과로 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 메서드에서 반환하는 컴포넌트에 키('키'라는 소품)를 제공해야 했습니다.renderRow 또는 renderSection에 키 추가헤더는 아무것도 하지 않았지만 renderSeparator에 추가하면 경고가 사라집니다.

를 입력해야 합니다.

키 속성이 있는 경우 ListView Rows(목록 보기 행)에서 다음을 수행하십시오.

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

그렇지 않은 경우 항목을 키로 추가해 보십시오.

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

횟수.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>
    );
}

그럼 해결됐군.

있는 합니다.<>루프 내 구조의 최상위 레벨로 지정합니다.

return <select>
    {Object.values(countries).map(c => {
        return (<>           {/*   <== EMPTY TAG!   */}
            <option value={c.id}>{c.name}</option>
            <States countryId={c.id} />
        </>)
    }
</select>

할 수 .<React.Fragment> 것이 <>키를 전체 태그에 추가합니다.

import {Fragment} from 'react';

return <select>
    {Object.values(countries).map(c => {
        return (<Fragment key={c.id}>   {/* You can also use <React.Fragment> without import */}
            <option value={c.id}>{c.name}</option>
            <States countryId={c.id} />
        </Fragment>)
    }
</select>

목록의 렌더링 루트 구성 요소에 프로펠러 '키'를 추가합니다.

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

이 경고는 목록 항목에 키를 추가하지 않을 때 발생합니다.react js Docs에 따라 -

키는 React가 변경, 추가 또는 제거된 항목을 식별하는 데 도움이 됩니다.요소를 안정적으로 식별하기 위해 배열 내의 요소에 키를 부여해야 합니다.

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

확인: 키 = undef!!

다음 경고 메시지도 표시됩니다.

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

코드가 완전히 올바른 경우, 하지만 만약 그렇다면

<MyComponent key={someValue} />

someValue가 정의되지 않았습니다!!!이것부터 확인해 주세요.시간을 절약할 수 있습니다.

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

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

이 경고의 키워드는 "고유", 섹션입니다.ID + 행ID는 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)}/>

콜드버펫과 네이더 다빗이 나를 이 길로 인도해 준 덕분이다.

제가 이해한 바로는 이렇습니다.츠키노뒤에 있는 예시와 같이 컴포넌트 목록을 렌더링해야 합니다.에는 '''를 합니다.key고유할 필요는 없습니다. it it it it it be it it 。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>),
    ];
}

두 가지 조건이 모두 충족된 것 같습니다.아마 키('연락처')가 문제일 것입니다.

 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

이 문제에 대해 제가 고민하게 된 것은 키가 제가 정의한 JSX 요소가 아닌 '실제'나 DOM HTML 요소에 적용된다고 생각했기 때문입니다.

물론 React에서는 가상 DOM을 사용하고 있기 때문에 정의된 React JSX 요소는<MyElement>다음과 같은 실제 DOM HTML 요소처럼 보이는 요소만큼 중요합니다.<div>.

이해 하셨나요?

제 경우 시멘틱 UI 리액트 "카드" 보기를 사용하고 있었습니다.작성한 각 카드에 키를 추가하면 다음과 같은 경고가 사라집니다.

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

이 오류는 부모 div에 키가 있는 경우에도 키 없이 루프 함수를 사용하여 HTML 요소를 렌더링할 때 발생합니다.이 문제를 해결하려면 키를 전달해야 합니다.

자세한 내용을 보려면 다음 스크린샷을 확인하십시오.

선택한 키를 확인하고 각 루프를 에 추가합니다.

상기 방법에 따라 이 경고를 수정했습니다.

이건 나한테 효과가 있었어.

<View>
    {
        array.map((element, index) => {
            return(
                <React.Fragment key= {`arrayElement${index}`}>
                    {element}
                </React.Fragment>
            );
        })
    }
</View>

를 사용하고 있는 경우는,<Fade in>반응 응용 프로그램의 요소를 추가하십시오.key={}속성을 지정하지 않으면 콘솔에 오류가 표시됩니다.

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

반응형