플랫리스트를 다시 렌더링하는 방법은 무엇입니까?


88

ListView와 달리 this.state.datasource를 업데이트 할 수 있습니다. FlatList를 업데이트하거나 다시 렌더링하는 방법이나 예제가 있습니까?

내 목표는 사용자가 버튼을 누를 때 텍스트 값을 업데이트하는 것입니다.

renderEntries({ item, index }) {
    return(
        <TouchableHighlight onPress={()=> this.setState({value: this.state.data[index].value+1})>
             <Text>{this.state.data[index].value}</Text>
        </TouchableHighlight>
    )
}

<FlatList 
    ref={(ref) => { this.list = ref; }} 
    keyExtractor={(item) => item.entry.entryId} 
    data={this.state.data} 
    renderItem={this.renderEntries.bind(this)} 
    horizontal={false} />

8
FlatList에 대한 문서는 "이것은 PureComponentprops가 얕은 상태로 유지되면 다시 렌더링되지 않음을 의미합니다. renderItem함수가 의존 하는 모든 것이 ===업데이트 이후 가 아닌 prop으로 전달 되는지 확인하십시오. 그렇지 않으면 UI가 업데이트되지 않을 수 있습니다. 여기에는 data소품 및 부모 구성 요소 상태가 포함됩니다. " 이 조언을 따르고 있습니까?
Jordan Running

3
extraData및으로 무엇을 시도해도 shouldItemUpdate목록을 다시 렌더링 할 수 없습니다. 내가 한 일은 상태를 지우고 렌더링을 기다린 다음 상태를 업데이트하는 것입니다. this.setState({ data: null }, () => { this.setState({ data: actualData }) });
여호수아 핀터

답변:


193

extraDataFlatList 구성 요소 에서 속성을 사용합니다 .

문서에 다음과 같이 설명되어 있습니다.

전달하여 extraData={this.state}FlatList우리가 확인 FlatList되면 자체를 다시 렌더링 state.selected변경됩니다. 이 소품을 설정하지 않으면 FlatList항목을 다시 렌더링해야한다는 것을 알지 못합니다. 이는 또한 a PureComponent이고 소품 비교에 변경 사항이 표시되지 않기 때문입니다 .


36
나는 redux를 사용하고 있으며 그 경우 데이터를 보내 거나 나를 위해 일 data={this.props.searchBookResults}하지 extraData={this.state}않습니다 extraData={this.props}. 그리고 data={this.props.searchBookResults}너무 작동하지 않습니다. 무엇을해야합니까?
Sujit

11
extraData :를 사용하여 <FlatList> 새로 고침... data={this.props.searchBookResults} extraData={this.state.refresh} onPress={()={this.setState({ refresh: !refresh})}
Nay

9
나는 같은 문제로 어려움을 겪고 있습니다. 그것은 내가 물려 중요하지 않습니다 extraData, 구성 요소가 :(하지 업데이 트 않습니다
데니스 Cappelini

2
@DenisCappelini, extraData하위 항목이 다시 렌더링되어야 할 때 소품 으로 전달 된 데이터가 변경 되는지 확인하십시오 . 예를 들어 목록 항목이 활성 / 비활성 일 수있는 경우 this.state개체 또는 this.props개체의 일부 가 내부로 들어가야 하는 항목인지 여부에 관계없이 상태 변수를 확인합니다 extraData. 커서 또는 활성 항목의 배열 등일 수 있습니다.
Emperor_Earth

1
@Sujit 동일한 문제가 발생했지만을 구현 shouldComponentUpdate()했거나 업데이트하거나 완전히 주석 처리하면 문서에 설명 된대로 작동하고 있다는 것을 깨달았습니다 .
JanithaR

54

빠르고 간단한 해결 방법 :

  1. 추가 데이터를 부울 값으로 설정합니다.

    extraData = {this.state.refresh}

  2. 목록을 다시 렌더링 / 새로 고침 할 때 부울 상태 값을 전환합니다.

    this.setState({ 
        refresh: !this.state.refresh
    })
    

이것이 바로 데이터 소품에 데이터를 추가 할 것이기 때문에 필요한 것입니다. 또한 그것은 React-Native 팀에 의한 매우 이상한 구현입니다 ... 데이터에 새로 고침 기능이나 속성을 갖는 것이 더 합리적입니다. IE : this.data.refresh(). 대신 부울을 설정하고 변경합니다. 부울 값 자체는 의미가 없으므로 그 안에 존재하는 점은 무엇입니까? ... (데이터를 올바르게 새로 고치는 것 외에 다른 점은 없습니까?)
YungGun

@HradeshKumar 나는 그것을하지만 데이터 내부의 마지막 항목은 사라질 수 없습니다!
DevAS 2019

이것은 매력처럼 작동하지만 this.state.users일부 사용자의 플래그를 변경했지만 여전히 작동하지 않는 이유 를 모르겠습니다 .
shyammakwana.me

나를 위해 작동하지 않습니다. 도와 주시겠습니까 : stackoverflow.com/questions/65547030/…
Gayatri Dipali

21

오 쉽 네요, 그냥 사용하세요 extraData

장면 뒤에서 추가 데이터가 작동하는 방식이 FlatList 이거나 VirtualisedList 가 일반 메서드 를 통해 개체가 변경되었는지 여부를 확인합니다 onComponentWillReceiveProps.

따라서해야 할 일은 extraData.

내가하는 일은 다음과 같습니다.

immutable.js를 사용 하고 있으므로보고 싶은 내용이 포함 된 Map (불변 객체)을 전달하기 만하면됩니다.

<FlatList
    data={this.state.calendarMonths}
    extraData={Map({
        foo: this.props.foo,
        bar: this.props.bar
    })}
    renderItem={({ item })=>((
        <CustomComponentRow
            item={item}
            foo={this.props.foo}
            bar={this.props.bar}
        />
    ))}
/>

그렇게 하면 불변 객체가 이전 객체와 다를 것이기 때문에 언제 this.props.foo또는 this.props.bar변경 CustomComponentRow하면 업데이트됩니다.


2
나는 마침내 이해했다 extraData! VirtualisedList코드 링크에 감사드립니다 !
Tushar Koul

hello, @ SudoPiz 마지막 항목을 삭제 한 후 Flatlist를 다시 렌더링하고 싶습니다.이 Q를 확인할 수 있습니다. stackoverflow.com/questions/58780167/…
Oliver D

6

OK. FlatList가 데이터 소품 외부의 데이터 변경을 알도록하려면 extraData로 설정해야하므로 지금 다음과 같이 설정해야합니다.

<FlatList data={...} extraData={this.state} .../>

참조 : https://facebook.github.io/react-native/docs/flatlist#extradata


2
가장 좋은 구현 ... 저는 데이터 소품과 동일하게 설정하는 것을 선호했기 때문에 상태가 변경 될 때 새로 고침되지 않습니다. 그러나 이것은 지금까지 가장 쉬운 구현입니다. 감사!
Robert Kehoe 19

안녕하세요, @MahdiBashirpour 내가 마지막 항목을 삭제 한 후 Flatlist를 다시 렌더링하려면,이 Q를 확인할 수 있습니다 stackoverflow.com/questions/58780167/...
올리버 D

4

Button이 있으면 onPress 내에서 setState로 데이터를 업데이트 할 수 있습니다. 그러면 SetState는 FlatList를 다시 렌더링합니다.


3
내 touchablehighlight에 setState가 있습니다. setState를 잘 작동되지만 flatlist는 상태 값들의 갱신을 도시되지 않은 -> this.state.value
shalonteoh

데이터 소스를 직접 업데이트하지 않기 때문에 FlastList의 값이 업데이트되지 않습니다. this.state.data는 FlatList로 렌더링되는 것이지만 onPress에서는 this.state.value 만 업데이트합니다.
WilliamC apr

미안 해요, 질문 오타. this.state.data [인덱스] .value되어야
shalonteoh

4

많은 검색과 실제 대답을 찾은 후에 마침내 나는 그것이 최고라고 생각하는 대답을 얻었습니다.

       <FlatList
      data={this.state.data}
      renderItem={this.renderItem}
      ListHeaderComponent={this.renderHeader}
      ListFooterComponent={this.renderFooter}
      ItemSeparatorComponent={this.renderSeparator}
      refreshing={this.state.refreshing}
      onRefresh={this.handleRefresh}
      onEndReached={this.handleLoadMore}
      onEndReachedThreshold={1}
      extraData={this.state.data}
      removeClippedSubviews={true}
      **keyExtractor={ (item, index) => index }**
              />
    .....

내 주요 문제는 (KeyExtractor) 나는 이것을 사용하지 않았습니다. 작동하지 않음 : keyExtractor = {(item) => item.ID} 내가 이것을 변경 한 후 매력처럼 작동했습니다. 누군가에게 도움이되기를 바랍니다.


당신은 가치 this.state.refreshing와 기능 을 넣을 수 handleRefresh있습니까?
DevAS

2

여기에 이전 답변에 대한 확장입니다. 확인해야 할 두 부분, extraData를 추가하고 keyExtractor가 고유한지 확인하십시오. keyExtractor가 일정하면 rerender가 트리거되지 않습니다.

<FlatList
data={this.state.AllArray}
extraData={this.state.refresh}
renderItem={({ item,index })=>this.renderPhoto(item,index)}
keyExtractor={item => item.id}
>
                                    </FlatList>

1

나는 추가하여이 문제를 해결 extraData={this.state}자세한 내용은 아래하십시오 체크 코드를

render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.arr}
          extraData={this.state}
          renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
        />
      </View>
    );
  }

0

나는 대체했다 FlatListSectionList하며 상태 변화에 제대로 업데이트입니다.

<SectionList
  keyExtractor={(item) => item.entry.entryId} 
  sections={section}
  renderItem={this.renderEntries.bind(this)}
  renderSectionHeader={() => null}
/>

명심해야 할 유일한 것은 sectiondiff 구조 가 있다는 것입니다.

const section = [{
  id: 0,
  data: this.state.data,
}]

0

저에게 트릭은 extraData 였고 항목 구성 요소를 한 번 더 드릴 다운했습니다.

state = {
  uniqueValue: 0
}

<FlatList
  keyExtractor={(item, index) => item + index}
  data={this.props.photos}
  renderItem={this.renderItem}
  ItemSeparatorComponent={this.renderSeparator}
/>

renderItem = (item) => {
  if(item.item.selected) {
    return ( <Button onPress={this.itemPressed.bind(this, item)}>Selected</Button> );
  }
  return ( <Button onPress={this.itemPressed.bind(this, item)}>Not selected</Button>);
}

itemPressed (item) {
  this.props.photos.map((img, i) => {
    if(i === item.index) {
      if(img['selected') {
        delete img.selected;
      } else {
        img['selected'] = true;
      }
      this.setState({ uniqueValue: this.state.uniqueValue +1 });
    }
  }
}

0

상호 작용에 의해 변경 될 변수를 extraData

당신은 창의적 일 수 있습니다.

예를 들어 체크 박스가있는 변경 목록을 처리하는 경우입니다.

<FlatList
      data={this.state.data.items}
      extraData={this.state.data.items.length * (this.state.data.done.length + 1) }
      renderItem={({item}) => <View>  


0

react-native-flatlist에서는 extraData라는 속성입니다. 플랫리스트에 아래 줄을 추가하십시오.

 <FlatList
          data={data }
          style={FlatListstyles}
          extraData={this.state}
          renderItem={this._renderItem}
       />

0

이 예에서 강제로 다시 렌더링하려면 변수를 변경하면됩니다. machine

const [selected, setSelected] = useState(machine)

useEffect(() => {
    setSelected(machine)
}, [machine])

-1

다음을 사용하십시오.

onRefresh={true}

flatList구성 요소 내부 .


1
이로 인해 오류가 발생합니다. 그런 다음 refreshing소품 을 사용해야합니다.
mahmoudafer

-1

Flatlist의 extraData가 나를 위해 작동하지 않았고 우연히 redux의 소품을 사용하고있었습니다. 이것은 ED209의 답변에 대한 의견의 문제와 유사하게 들렸습니다. 나는 소품을 받으면 수동으로 setState를 호출했습니다.

componentWillReceiveProps(nextProps: StateProps) {
    if (this.props.yourProp != null && nextProps.yourProp) {
        this.setState({ yourState: processProp(nextProps.yourProp) });
    }
}


<FlatList
  data={this.state.yourState}
  extraData={this.state.yourState}
/>

> React 17을 사용하는 사람들은 getDerivedStateFromProps를 사용하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.