首页 > 解决方案 > 模态和平面列表

问题描述

我从事我的第一个 react-native 项目,这也是我的第一个 javascript 工作。我至少想要一个带有自己数据库信息的新闻应用程序。后端已经完成。现在我正在与应用程序斗争-我想要一个带有模态的弹出窗口,其中包含来自我的 api 的信息,如 news_image、news_content 和 news_title。新闻在 FlatList 中,现在我想单击一个项目以在模式弹出窗口中显示内容。所以,这是我挣扎的代码。我总是出错。那么我该如何解决这个问题呢?坦克很多!

import React from "react";
import {
  AppRegistry,
  FlatList,
  Image,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  ActivityIndicator,
  ListView,
  YellowBox,
  Alert,
  TextInput
} from "react-native";
import { WebBrowser } from "expo";
import Button from "react-native-button";
import Modal from "react-native-modalbox";
import Slider from "react-native-slider";
import { MonoText } from "../components/StyledText";
export default class NewsFeed extends React.Component {
  static navigationOptions = {
    title: "HomeScreen"
  };
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true
    };
    YellowBox.ignoreWarnings([
      "Warning: componentWillMount is deprecated",
      "Warning: componentWillReceiveProps is deprecated"
    ]);
  }
  FlatListItemSeparator = () => {
    return (
      <View
        style={{
          height: 0.5,
          width: "100%",
          backgroundColor: "#000"
        }}
      />
    );
  };
  webCall = () => {
    return fetch("http://XXXXXXXXXXXX.com/connection.php")
      .then(response => response.json())
      .then(responseJson => {
        this.setState(
          {
            isLoading: false,
            dataSource: responseJson
          },
          function() {
            // In this block you can do something with new state.
          }
        );
      })
      .catch(error => {
        console.error(error);
      });
  };
  onClose() {
    console.log("Modal just closed");
  }
  onOpen() {
    console.log("Modal just opened");
  }
  onClosingState(state) {
    console.log("the open/close of the swipeToClose just changed");
  }
  componentDidMount() {
    this.webCall();
  }
  render() {
    if (this.state.isLoading) {
      return (
        <View
          style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
        >
          <ActivityIndicator size="large" />
        </View>
      );
    }
    return (
      <View style={styles.MainContainer}>
        <FlatList
          data={this.state.dataSource}
          ItemSeparatorComponent={this.FlatListItemSeparator}
          renderItem={({ item }) => (
            <View style={{ flex: 1, flexDirection: "row" }}>
              <Image
                source={{ uri: item.news_image }}
                style={styles.imageView}
              />
              <Text
                onPress={() => this.refs.modal.open()}
                style={styles.textView}
              >
                {item.news_title}
                {"\n"}
                <Text style={styles.textCategory}>{item.author}</Text>
              </Text>
              <Text style={styles.textViewDate}>{item.created_at}</Text>
              <Modal
                style={[styles.modal]}
                position={"bottom"}
                ref={"modal"}
                swipeArea={20}
              >
                <ScrollView>
                  <View style={{ width: "100%", paddingLeft: 10 }}>
                    {item.news_content}
                  </View>
                </ScrollView>
              </Modal>
            </View>
          )}
          keyExtractor={(item, index) => index.toString()}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  MainContainer: {
    justifyContent: "center",
    flex: 1,
    margin: 5
  },
  imageView: {
    width: "25%",
    height: 100,
    margin: 7,
    borderRadius: 7
  },
  textView: {
    width: "100%",
    height: "100%",
    textAlignVertical: "center",
    padding: 10,
    fontSize: 20,
    color: "#000"
  },
  textViewDate: {
    width: "30%",
    textAlignVertical: "center",
    padding: 15,
    color: "#afafaf"
  },
  textCategory: {
    color: "#d3d3d3",
    fontSize: 12
  },
  modal: {
    justifyContent: "center",
    alignItems: "center",
    height: "90%"
  }
});

标签: react-nativereact-native-flatlist

解决方案


检查下面的代码并将其与您的代码进行比较。

我不确定您的错误在哪里或您的确切错误是什么,但您可以查看下面与您的类似的示例代码进行比较。

由于自动转换为 JSON 和其他一些有益的东西,我在 fetch() 上使用了“ Axios ” 。

npm install --save axios

代码:

import React, { Component } from 'react'
import {
    ActivityIndicator,
    FlatList,
    Image,
    ScrollView,
    Text,
    TouchableOpacity,
    View
} from 'react-native';
import Axios from 'axios';
import Modal from "react-native-modalbox";

export default class NewsFeed extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: [],
            selectedIndex : -1
        }
    }

    componentDidMount = () => {
        Axios.get('<URL>')
            .then(response => {
                const { data } = response;
                this.setState({dataSource : data});
            }).catch(error => {
                const { data } = error;
                console.log(data);
            });
    }

    _openModal = index => {
        this.setState({ selectedIndex : index });
        this.modalReference.open();
    }

    _renderSeparator = () => {
        return <View style={{ flex: 1, borderBottomWidth: 0.5, borderBottomColor: '#000000' }} />
    }

    _renderItem = ({item, index}) => {
        const {news_image, news_title, news_content, author, created_at} = item;

        return <TouchableOpacity onPress={() => this._openModal(index)} >
            <View style={{ flex: 1, flexDirection: 'row' }}>
                <Image style={{ flex: 1, width: null, height: 200 }} source={{ uri: news_image }} />
                <Text>{news_title}</Text>
                <Text>{author}</Text>
                <Text>{created_at}</Text>
            </View>
        </TouchableOpacity>;
    }

    render = () => {
        const { dataSource, selectedIndex } = this.state;
        const { news_content } = dataSource[selectedIndex];

        return dataSource.length === 0 ? 
            <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
              <ActivityIndicator size="large" />
            </View> : 
            <View style={styles.MainContainer}>
                <FlatList
                    data={dataSource}
                    keyExtractor={(item, index) => index.toString()}
                    ItemSeparatorComponent={this._renderSeparator}
                    renderItem={this._renderItem}
                />
                <Modal ref={reference => modalReference = reference}>
                    <ScrollView style={{ flex: 1, padding: 20 }}>
                        <Text>{news_content}</Text>
                    </ScrollView>
                </Modal>
            </View>
    }
}

推荐阅读