React Native:以Modal显示FlatList数据

时间:2019-02-18 01:12:15

标签: react-native react-native-flatlist

我有一个反应本机平面列表,该列表使用wp rest api从Wordpress网站呈现一些数据。平面列表正确显示了帖子,当单击时,它会打开模式,但是将状态推到模式时遇到了一些麻烦。

当前,模式打开时,它对平面列表中的每个项目都显示相同的内容(最后一个帖子/项目)。有什么建议么?任何帮助表示赞赏。

import React, { Component } from 'react';
import {
  Image, Dimensions, View, ActivityIndicator, TouchableOpacity, TouchableHighlight,
  WebView, ScrollView, StyleSheet, ImageBackground, FlatList, Text
} from 'react-native';
import Moment from 'moment';
import HTML from 'react-native-render-html';
import Modal from "react-native-modal";

export default class LatestNews extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isModalVisible: false,
      isLoading: true,
      posts: [],
      id: null,
    };
  }


  componentDidMount() {
    fetch(`http://mywebsite.com/wp-json/wp/v2/posts/?_embed&categories=113`)
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          posts: responseJson,
        })
      })
      .catch((error) => {
        console.error(error);
      });
  }

  _toggleModal = () =>
  this.setState({
    isModalVisible: !this.state.isModalVisible,
  });


  _renderItem = ({item}) => {
    return (
      <TouchableOpacity onPress={() => this._onPressItem(item.id)} key={item.id}>
        <View>
        {item._embedded['wp:featuredmedia'].filter(
                    element => element.id == item.featured_media
                  ).map((subitem, index) => (
                    <View style={{
                      margin: '5%',
                      borderWidth: 1,
                      borderColor: '#d8d8d8',
                      borderRadius: 10,
                      shadowColor: '#000',
                      shadowOffset: { width: 0, height: 5 },
                      shadowOpacity: 0.2,
                      shadowRadius: 8,
                      elevation: 1,
                    }}>
                    <ImageBackground
                      style={styles.news}
                      source={{ uri: subitem.media_details.sizes.medium.source_url }}
                      key={item.id}>
                        <View style={styles.itemTitle}>
                          <Text style={{ fontSize: 16, fontWeight: 'bold' }}>
                            {item.title.rendered}
                          </Text>
                        </View>

                      </ImageBackground>
                      </View>
                  ))}
        </View>
      </TouchableOpacity>
    )
  };

  _onPressItem(id) {
    this.setState({
      isModalVisible: true,
      id: id,
    });
  };

  render() {
    if (this.state.isLoading == true) {
      return (
        <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center', alignItems: 'center', }}>
          <ActivityIndicator size="large" color="#1C97F7" />
        </View>
      )
    }
    else {
      Moment.locale('en');
      return (
        <View>
         {this.state.posts.map((item, index) => (
          <Modal isVisible={this.state.isModalVisible} id={this.state.id}>
          {item._embedded['wp:featuredmedia'].filter(
                    element => element.id == item.featured_media
                  ).map((subitem, index) => (
                        <ScrollView style={
                          { flex: 1, backgroundColor: 'white', padding: 20, paddingBottom: 40,}
                          }>
                    <ImageBackground
                      style={styles.news}
                      source={{ uri: subitem.media_details.sizes.medium.source_url }}
                      key={item.id} />
                      <TouchableOpacity onPress={this._toggleModal}>
                    <Text>Hide me!</Text>
                    </TouchableOpacity>
                  <HTML 
                  tagsStyles={{
                    body: {fontSize: 16, paddingBottom: 20,}, 
                    p: {fontSize: 16, fontWeight: "normal", marginTop: 10, marginBottom: 20}, 
                    strong: {fontSize: 20,}, 
                    blockquote: {fontSize: 20}, 
                    a: {fontSize: 16, color: "#0044e2"}, 
                    em: {fontSize: 20,}, 
                    img: {height: 250, width: 350}, 
                  }}
                  key={item.id}
                  styleName="paper md-gutter multiline" 
                  html={item.content.rendered} 
                  imagesMaxWidth={Dimensions.get('window').width * .9} 
                  ignoredStyles={['width', 'height', 'video']}
                />
                </ScrollView>
                ))}
                  </Modal>
        ))}
        <FlatList
          data={this.state.posts}
          renderItem={this._renderItem}   
          keyExtractor={(item, index) => index}
          />
        </View>
      )
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    paddingTop: 0,
  },
  h1: {
    color: 'black',
    fontSize: 24,
    paddingTop: 20,
    fontWeight: 'bold',
  },
  h2: {
    color: 'black',
    fontSize: 24,
    paddingTop: 20,
    fontWeight: 'bold',
  },
  h3: {
    fontSize: 13,
  },
  button: {
    width: '45%',
    margin: 5,
    backgroundColor: '#492661',
    padding: 8,
    height: 36,
    borderRadius: 18,
  },
  buttonGrey: {
    width: '45%',
    margin: 5,
    backgroundColor: '#353535',
    padding: 8,
    height: 36,
    borderRadius: 18,
  },
  buttonText: {
    color: 'black',
    alignSelf: 'center',
  },
  highlight: {
    backgroundColor: '#f5f5f5',
    borderRadius: 50,
    width: 100,
    height: 100,
    marginRight: 20,
    alignItems: 'center',
    justifyContent: 'center',
    borderColor: 'gold',
    borderWidth: 0,
  },
  news: {
    backgroundColor: '#f5f5f5',
    borderRadius: 10,
    width: '100%',
    height: 200,
    overflow: 'hidden',
  },
  hero: {
    backgroundColor: '#492661',
    width: '110%',
    height: 260,
    alignSelf: 'center',
    marginTop: 0,
    overflow: 'hidden'
  },
  itemTitle: {
    backgroundColor: 'rgba(255,255,255,0.9)',
    paddingVertical: 10,
    position: 'absolute',
    bottom: 0,
    right: 0,
    width: '100%',
    paddingHorizontal: 10,
  },
});

1 个答案:

答案 0 :(得分:0)

在FlatList中,这是一个问题,如果存在dataModel,则无法再次重新呈现。为此,您可以使用: 在FlatList中有一个propsTypes: ExtraData = {} ,您应该在其中添加一个新的布尔状态,并且无论在何处再次将数据添加到flatlist中。设置该布尔键的状态,这将对您有所帮助:

<FlatList
          data={this.state.posts}
          renderItem={this._renderItem}   
          keyExtractor={(item, index) => index}
          extraData={this.state.extraData}
          />

要在其中添加flatList数据的位置再次添加以下行:

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

通过此行渲染方法再次运行,您将找到一个新的更新记录。

使用此功能,对我有帮助。

相关问题