React-Native FlatList не перерисовывается с помощью пользовательского renderItem

У меня есть FlatList, который работает, как и ожидалось, при использовании простого старого тега <Text>, но при использовании пользовательского компонента внутри renderItem FlatList не будет повторно отображаться при изменении this.state.dayOfYear. При загрузке приложения, когда я устанавливаю this.state.dayOfYear, оно загружается правильно. Но когда я снова изменю состояние, он не изменит FlatList.

Код FlatList

<FlatList
    style={{flex: 1}}
    extraData={this.state}
    data={reading_data[this.state.dayOfYear]}
    renderItem={({item}) => <DayRow content={item}/>} //does not work
    // renderItem={({item}) => <Text>{item.ref}</Text>} //Works perfectly
    keyExtractor={(item, index) => index}
/>

Пользовательский элемент рендеринга (DayView.js)

import {StyleSheet, Text, View} from 'react-native'
import React, {Component} from 'react';

export default class DayRow extends React.Component {

    constructor(props) {
        super(props)
        console.log(props)
        this.state = {
            content: props.content,
        }
    }

    render() {
        return (
            <View style={styles.row}>
                <Text style={styles.text}>{this.state.content.ref}</Text>
                <View style={{height: 2, backgroundColor:'#abb0ab'}}/>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    row: {
        backgroundColor: '#fff'
    },
    text: {
        fontSize: 16,
        padding: 10,
        fontWeight: 'bold',
        color: '#000',
    },
});

module.exports = DayRow;

person jaytj95    schedule 18.01.2018    source источник


Ответы (2)


Я почти уверен, что ваши DayRow элементы создаются до того, как props.content будет установлен, вам нужно захватить реквизит, когда компонент монтируется. Попробуйте добавить это:

componentWillMount() {
  const { content } = this.props;
  this.setState({content: content});
}

РЕДАКТИРОВАТЬ Я пропустил часть о "повторном рендеринге"... В основном вам нужен блок кода, который обновляет состояние ваших компонентов при изменении его свойств, реагирующие компоненты имеют другую функцию, похожую на componentWillMount, называемую componentWillReceiveProps, попробуйте :

componentWillReceiveProps(nextProps) {
  const { content } = nextProps;
  this.setState({content: content});
}
person tay_rex    schedule 18.01.2018
comment
Хороший улов, но не кости :( - person jaytj95; 18.01.2018
comment
@jaytj95 jaytj95 Я что-то пропустил в ОП. Проверьте мою правку. - person tay_rex; 18.01.2018
comment
Красиво работает! Итак, чтобы понять это правильно, когда я обновляю состояние, FlatList повторно использует уже отрендеренные компоненты? У меня сложилось впечатление, что он заменит старые компоненты из renderItem новыми (заменит старые DayRows новыми DayRows). - person jaytj95; 18.01.2018
comment
@ jaytj95 Jaytj95 Я думаю, что реализация FlatList имеет некоторую оптимизацию для использования ранее созданных элементов, когда это возможно. Хотя я не уверен во всех деталях. - person tay_rex; 18.01.2018
comment
спасибо @tay_rex. componentWillReceiveProps отлично сработал для меня. - person Ravi; 28.07.2020

У меня была такая же проблема, но она была решена с помощью extraData = {this.state}

Полный код здесь

<FlatList
  style={styles.listView}
  data={this.state.readingArray}
  extraData={this.state}
  renderItem=
  {({item})=>
person Akhzar Nazir    schedule 30.05.2018