Редактирование состояния каждого элемента плоского списка

#react-native #state #react-native-flatlist

#react-native #состояние #react-native-плоский список

Вопрос:

Я создал страницу, в которой я использую FlatList. В этом плоском списке используется созданный мной компонент item, который при нажатии отображает другой вид под собой, установив для состояния «скрыто» значение false. Основная проблема, с которой я сталкиваюсь, заключается в том, что я не могу найти способ изменить «скрытое» состояние на true при нажатии одного из элементов, поэтому всегда сохраняю только 1 элемент, отображающий дополнительный вид в данный момент. В то же время, когда я обновляю / повторно отображаю свой плоский список, он не возвращает всему «скрытому» состоянию значение true.

Здесь я отображаю свой FlatList

 _onRefresh() {
    this.setState({refreshing: true}, () => this._loadList());
}

render() {
    return (
        <View style={[style.container, style.whiteBackground]}>
            <CategoryFilter filterCallback={this._changeCategory}/>
            <FlatList
                data={this.state.list}
                extraData={this.state}
                renderItem={({item}) =>
                    <ListItemComponent item={item} category={this.state.category}/>
                }
                refreshing={this.state.refreshing}
                onRefresh={() => this._onRefresh()}
            />
        </View>
    );
}
  

И именно здесь я визуализирую и отображаю скрытый вид

 constructor(props) {
    super(props);
    this.state = {
        hidden: true
    };
}

componentDidMount() {
    this.setState({hidden: true});
}

_onPress() {
    this.setState({
        hidden: !this.state.hidden
    });
}

[...]

_renderOS(item) {
    if (Platform.OS === 'android') {
        return (
            <TouchableNativeFeedback onPress={() => this._onPress()}>
                {this._renderItem(item)}
            </TouchableNativeFeedback>
        );
    } else if (Platform.OS === 'ios') {
        return(
            <TouchableOpacity onPress={() => this._onPress()}>
                {this._renderItem(item)}
            </TouchableOpacity>
        );
    }
}

[...]

_renderDescription(item) {
    if (this.state.hidden === true) {
        return null;
    } else {
        return (
            <View style={listItemStyle.descriptionContainer}>
                <Text style={listItemStyle.description}>
                    {item.description}
                </Text>
            </View>
        );
    }
}
  

Я просто хочу иметь возможность иметь только один элемент списка со скрытым, для которого в данный момент установлено значение false, и указать, что для указанного элемента должно быть установлено значение hidden = true при обновлении страницы, но я так и не нашел ничего, что могло бы мне помочь.

Ответ №1:

Итак, после долгих размышлений я наконец нашел решение. Вместо того, чтобы обрабатывать скрытое состояние в каждом элементе, я составил список каждого скрытого состояния, связанного с идентификаторами элементов в компоненте, в котором находится мой плоский список, добавив функцию, которая установит для ранее открытого элемента значение hidden и откроет новый, и передаст его в качестве обратного вызова для моих элементов, чтобы его можно было вызывать при нажатии на них.

 _onPress(id) {
    let items;

    items = this.state.items.map((item) => {
        if (item.id === this.state.openId)
            item.open = false;
        else if (item.id === id)
            item.open = true;
        return item;
    });
    this.setState({
        items: items,
        openId: (id === this.state.openId ? '' : id)
    });
}

            <FlatList
                data={this.state.items}
                extraData={this.state}
                renderItem={({item}) =>
                    <ListItemComponent
                        onPress={this._onPress.bind(this)}
                        bet={item}
                        categoryList={this.state.categoryList}
                        open={item.open}/>
                }
                refreshing={this.state.refreshing}
                onRefresh={() => this._onRefresh()}
            />