Làm thế nào để hiển thị lại danh sách phẳng?


86

Không giống như ListView, chúng tôi có thể cập nhật this.state.datasource. Có phương pháp hoặc ví dụ nào để cập nhật FlatList hoặc kết xuất lại nó không?

Mục tiêu của tôi là cập nhật giá trị văn bản khi người dùng nhấn nút ...

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
Các tài liệu cho FlatList nói: "Đây là một PureComponentcó nghĩa là nó sẽ không tái làm nếu đạo cụ vẫn shallow- bằng nhau. Hãy chắc chắn rằng tất cả mọi thứ bạn renderItemchức năng phụ thuộc vào được thông qua như là một chỗ dựa đó không phải là ===sau khi cập nhật, nếu không UI của bạn có thể không cập nhật về các thay đổi. Điều này bao gồm datatrạng thái thành phần phụ và chính. " Bạn có đang làm theo lời khuyên này không?
Jordan Running

3
Bất kể tôi đã cố gắng làm gì extraDatashouldItemUpdate, tôi không thể có được danh sách để hiển thị lại. Cuối cùng, những gì tôi làm là xóa trạng thái, chờ điều đó hiển thị và sau đó cập nhật trạng thái. this.setState({ data: null }, () => { this.setState({ data: actualData }) });
Joshua Pinter,

Câu trả lời:


186

Sử dụng thuộc extraDatatính trên thành phần FlatList của bạn.

Như tài liệu nói:

Bằng cách chuyển extraData={this.state}cho FlatListchúng tôi đảm bảo FlatListsẽ tự hiển thị lại khi các state.selectedthay đổi. Nếu không đặt chỗ dựa này, FlatListsẽ không biết nó cần kết xuất lại bất kỳ mục nào vì nó cũng là một PureComponentvà so sánh chống đỡ sẽ không hiển thị bất kỳ thay đổi nào.


34
Tôi đang sử dụng redux và trong trường hợp đó, việc gửi dữ liệu giống như data={this.props.searchBookResults}và không extraData={this.state}cũng như không hiệu extraData={this.props}quả với tôi. Và data={this.props.searchBookResults}cũng không hoạt động. Để làm gì?
Sujit

8
Sử dụng extraData: để làm mới của bạn <FlatList>... data={this.props.searchBookResults} extraData={this.state.refresh} onPress={()={this.setState({ refresh: !refresh})}
Nay

9
Tôi đang đấu tranh với cùng một vấn đề. Nó không quan trọng những gì tôi truyền lại extraData, thành phần không cập nhật :(
Denis Cappelini

2
@DenisCappelini, hãy đảm bảo dữ liệu được chuyển vào các phần mềm extraDatachống thay đổi khi [các] mục con phải hiển thị lại. Ví dụ: nếu các mục danh sách có thể hoạt động / không hoạt động, hãy đảm bảo rằng biến trạng thái đó, cho dù một phần của this.stateđối tượng hay this.propsđối tượng là thứ nên đi vào bên trong extraData. Nó có thể là một con trỏ hoặc một mảng các mục đang hoạt động, v.v.
Emperor_Earth

1
@Sujit Tôi đang gặp phải vấn đề tương tự nhưng sau đó tôi nhận ra rằng tôi đã triển khai shouldComponentUpdate(), sau khi tôi cập nhật hoặc hoàn toàn nhận xét, mọi thứ đang hoạt động giống như mô tả trong tài liệu.
JanithaR

51

Để có giải pháp nhanh chóng và đơn giản Hãy thử:

  1. đặt dữ liệu bổ sung thành giá trị boolean.

    extraData = {this.state.refresh}

  2. Chuyển đổi giá trị của trạng thái boolean khi bạn muốn hiển thị lại / làm mới danh sách

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

Đó chính xác là những gì tôi cần vì tôi sẽ thêm dữ liệu vào chỗ dựa dữ liệu. Ngoài ra, đó là một triển khai siêu kỳ lạ của nhóm React-Native ... sẽ có ý nghĩa hơn nếu có một chức năng hoặc thuộc tính làm mới trên dữ liệu. IE: this.data.refresh(). Thay vào đó, chúng tôi đặt boolean và thay đổi nó. Các phép toán luận đánh giá cao bản thân không có ý nghĩa, như vậy là những gì các điểm trong nó hiện ... (Không có điểm, không phải là làm cho dữ liệu làm mới phải không?)?
YungGun

@HradeshKumar Tôi làm điều đó nhưng mục cuối cùng bên trong Dữ liệu nó không thể biến mất!
DevAS

điều này hoạt động giống như sự quyến rũ, nhưng tôi vẫn không biết tại sao this.state.userskhông hoạt động, mặc dù tôi đã thay đổi cờ ở một số người dùng.
shyammakwana.me

21

Ồ, thật dễ dàng, chỉ cần sử dụng extraData

Bạn thấy cách dữ liệu bổ sung hoạt động đằng sau hậu trường là FlatList hoặc VirtualisedList chỉ kiểm tra ướt đối tượng đó đã thay đổi thông qua một onComponentWillReceivePropsphương thức bình thường .

Vì vậy, tất cả những gì bạn phải làm là đảm bảo rằng bạn cung cấp một cái gì đó thay đổi cho extraData.

Đây là những gì tôi làm:

Tôi đang sử dụng immutable.js nên tất cả những gì tôi làm là chuyển một Bản đồ (đối tượng không thể thay đổi) chứa bất cứ thứ gì tôi muốn xem.

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

Theo cách đó, khi nào this.props.foohoặc this.props.barthay đổi, chúng ta CustomComponentRowsẽ cập nhật, bởi vì đối tượng không thay đổi sẽ khác với đối tượng trước đó.


2
cuối cùng tôi đã hiểu extraData! cảm ơn cho liên kết đến VirtualisedListmã!
Tushar Koul

xin chào, @ SudoPiz Tôi muốn hiển thị lại Danh sách phẳng sau khi xóa mục cuối cùng, có thể kiểm tra Q stackoverflow.com/questions/58780167/…
Oliver D

6

OK, tôi vừa phát hiện ra rằng nếu chúng ta muốn FlatList biết sự thay đổi dữ liệu bên ngoài data prop, chúng ta cần đặt nó thành extraData, vì vậy tôi làm như sau:

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

tham khảo: https://facebook.github.io/react-native/docs/flatlist#extradata


1
Cách triển khai tốt nhất ... Tôi muốn đặt nó giống như chỗ dựa dữ liệu, vì vậy nó không làm mới khi bất kỳ thứ gì trong trạng thái thay đổi, nhưng đây là cách triển khai DỄ DÀNG NHẤT cho đến nay. Cảm ơn!
Robert Kehoe

xin chào, @MahdiBashirpour Tôi muốn hiển thị lại Flatlist sau khi xóa mục cuối cùng, có thể kiểm tra Q stackoverflow.com/questions/58780167/…
Oliver D

4

Nếu bạn sắp có Nút, bạn có thể cập nhật dữ liệu bằng setState bên trong onPress. SetState sau đó sẽ hiển thị lại FlatList của bạn.


2
có một setState trong ánh sáng có thể chạm vào của tôi. các setstate đang làm việc tốt nhưng flatlist không hiển thị cập nhật của giá trị nhà nước -> this.state.value
shalonteoh

Các giá trị trong FlastList của bạn không cập nhật vì bạn không cập nhật trực tiếp nguồn dữ liệu. this.state.data là những gì được hiển thị với FlatList, nhưng trong onPress, bạn chỉ cập nhật this.state.value.
WilliamC

xin lỗi lỗi của tôi, câu hỏi đánh máy. phải là this.state.data [index] .value
shalonteoh

3

sau rất nhiều tìm kiếm và tìm kiếm câu trả lời thực sự cuối cùng tôi đã có câu trả lời mà tôi nghĩ nó là tốt nhất:

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

vấn đề chính của tôi là (KeyExtractor) tôi đã không sử dụng nó như thế này. không hoạt động: keyExtractor = {(item) => item.ID} sau khi tôi thay đổi thành này, nó hoạt động như một sự quyến rũ, tôi hy vọng điều này sẽ giúp ai đó.


bạn có thể đặt giá trị của this.state.refreshingvà chức năng handleRefresh?
DevAS

1

Tôi đã giải quyết vấn đề này bằng cách thêm extraData={this.state}Vui lòng kiểm tra mã bên dưới để biết thêm chi tiết

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

1

Chỉ là một phần mở rộng về các câu trả lời trước đây ở đây. Hai phần cần đảm bảo, Đảm bảo rằng bạn thêm extraData và keyExtractor của bạn là duy nhất. Nếu keyExtractor của bạn không đổi, kết xuất sẽ không được kích hoạt.

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

0

Tôi đã thay thế FlatListbằng SectionListvà nó là các bản cập nhật đúng về sự thay đổi trạng thái.

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

Điều duy nhất cần ghi nhớ là sectioncó cấu trúc khác nhau:

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

0

Đối với tôi, mẹo là thêm Dữ liệu và đi sâu vào thành phần vật phẩm một lần nữa

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

Đặt các biến sẽ được thay đổi bởi sự tương tác của bạn tại extraData

Bạn có thể sáng tạo.

Ví dụ: nếu bạn đang xử lý một danh sách thay đổi với các hộp kiểm trên chúng.

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

0

Nếu chúng ta muốn FlatList biết dữ liệu thay đổi cả prop và state , chúng ta có thể xây dựng một đối tượng tham chiếu đến cả prop và state và làm mới danh sách phẳng.

const hasPropOrStateChange = { propKeyToWatch: this.props, ...this.state};
<FlatList data={...} extraData={this.hasPropOrStateChange} .../>

Tài liệu: https://facebook.github.io/react-native/docs/flatlist#extradata


0

Trong danh sách phản ứng-native-phẳng, chúng là một thuộc tính được gọi là extraData. thêm dòng dưới đây vào danh sách phẳng của bạn.

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

0

Trong ví dụ này, để buộc hiển thị lại, chỉ cần thay đổi biến machine

const [selected, setSelected] = useState(machine)

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

-1

Chỉ dùng:

onRefresh={true}

bên trong flatListthành phần của bạn .


1
điều này tạo ra một lỗi, sau đó bạn cần sử dụng refreshingprop
mahmoudafer

-1

ExtraData của Flatlist không hoạt động với tôi và tôi tình cờ sử dụng một phần mềm hỗ trợ từ redux. Điều này có vẻ tương tự với các vấn đề từ các nhận xét trong câu trả lời của ED209. Tôi đã kết thúc việc gọi setState theo cách thủ công khi tôi nhận được phần mềm hỗ trợ.

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

Đối với những người bạn sử dụng> React 17, hãy sử dụng getDerivedStateFromProps

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.