React-native Flatlist问题不使用fetch api呈现单个项目

时间:2018-06-14 07:20:19

标签: react-native react-native-flatlist

我正在使用平面列表并使用fetch API来创建一些项目,但是当我根据另一页面上的id发送项目时,它不会显示任何内容。在另一个页面上,我根据id获取JSON数据。它没有显示的数据。 当我创建本地JSON时,它也会渲染单个项目,但是当我使用获取的JSON时则不会。 这是我的代码我有一个按钮详细信息在renderItem函数,当我点击它进入描述页面,我正在获取json使用组件中的fetch确实挂载。但根据id它不是渲染因为我需要一个特定的产品描述。

 constructor(props) {
    console.log('constructer called');
    super(props)

    this.AddToCart = this.AddToCart.bind(this);
    this.renderItem = this.renderItem.bind(this);

    this.state =
        {
            showToast: false,
            qty:0,
            dataSource: [],                
            opacity: new Animated.Value(0)

        }
}




 renderItem = ({ item }) => {


    console.log('all the items from SliderProductPage  ' + item.name + ' is  ' + JSON.stringify(item.category_id));

    return (

        <View style={{ flex: 1, flexDirection: 'column', }}>


            <View style={{

                justifyContent: 'center',
                alignItems: 'center',
                borderBottomWidth: responsiveHeight(0.2),
                marginHorizontal: responsiveHeight(5),
                borderBottomColor: 'tomato',
                //backgroundColor: this.props.index % 2 == 0 ? 'mediumseagreen': 'tomato'                
                //backgroundColor: 'tomato'
            }}>

                <Animated.Image
                    onLoad={this.onLoad}
                    {...this.props}
                    source={{ uri: item.item_url }}
                    style={{
                        opacity: this.state.opacity,
                        transform: [
                            {
                                scale: this.state.opacity.interpolate({
                                    inputRange: [0, 2],
                                    outputRange: [0.85, 1]


                                })
                            }],
                        width: responsiveHeight(40),
                        height: responsiveHeight(35),
                        justifyContent: 'center',
                        marginTop: responsiveHeight(3),
                        alignItems: 'center'

                    }}
                >

                </Animated.Image>


                <View style={{justifyContent:'center', alignItems: 'center', marginBottom:responsiveHeight(2), }}>
                     <Text style={{ fontSize: responsiveFontSize(1.6), color: 'red', }}> {item.name} </Text>
                    <Text style={{ fontSize: responsiveFontSize(1.6), color: 'red', }}> $ {item.price} </Text>
                    <Text style={{ fontSize: responsiveFontSize(1.6), color: '#000000', marginHorizontal: responsiveHeight(2) }}>{item.description} </Text>
                </View>


                <View style={{

                    marginBottom: responsiveHeight(1.5),
                    flexDirection: 'row',
                    alignItems: 'center',

                }}>

                    <TouchableNativeFeedback activeOpacity={.5} onPress={() => this.props.navigation.navigate('ProductDescription', { id: item.id }, console.log("ProductDetails-SliderProductPage sending id-------" + JSON.stringify(item.id)))}
                        background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
                        <View style={styles.button}>
                            <Text style={styles.buttonText}>Details</Text>
                        </View>
                    </TouchableNativeFeedback>

                    <TextInput 
                    onChangeText={(update)=> this.setState({qty:update})}
                    keyboardType="numeric"  placeholder="0" placeholderTextColor="red"  underlineColorAndroid="transparent"
                    style={{padding:0,
                        borderWidth:0.5,
                        borderColor:'green',
                        height:responsiveHeight(4),
                        width:responsiveWidth(10),
                        color:'red',
                        //alignContent:'center'
                        textAlign:'center'
                    }} >

                        {this.state.quantity}
                    </TextInput>


                    <TouchableNativeFeedback  onPress={this.AddToCart.bind(this,item)}
                        //()=>this.props.navigation.navigate('AddCartItems',{id:item.id,name:item.name},console.log("SliderProductPage sending id and name to ADD to cart page-------"+JSON.stringify(item.id+" and "+item.name),alert(item.name+ "  Added ")))} 
                        background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
                        <View style={styles.button}>
                            <Text  style={styles.buttonText}>Add</Text>

                        </View>
                    </TouchableNativeFeedback>

                </View>
            </View>
            <View style={{
                height: 1,

                backgroundColor: 'white'

            }}>

            </View>


        </View>




    )
}



 componentDidMount() {
    console.log("we are on slider page componentDidMount function")
    const { navigation } = this.props;
    const id = navigation.getParam('id', 'NOT A ID');
    const name = navigation.getParam('name', 'not a valid name')
    console.log("here is id fetch data" + JSON.stringify(id) + ":::::::::SliderPage::::::::::" + JSON.stringify(name))

    const url = 'http://192.168.0.105:8081/products/get/alldata/item?category_id=' + id;

    fetch(url)
        .then((response) => response.json())
        .then((responseJson) => {
            this.setState({
                dataSource: responseJson.Category,


            }, console.log("**************helo it is response sliderPage data********************" + JSON.stringify(responseJson.Category)))

        })
        .catch((error) => {
            console.log(error);
        })
}


   render() {

    var textValue = this.state;
    console.log("we are on slider page  render Function")

    const { navigate } = this.props.navigation;
    const { navigation } = this.props;
    const id = navigation.getParam('id', 'not an valid id');
    const name = navigation.getParam('name', 'not a valid name')
    console.log(id);

    return (
        <View>

            <FlatList
                extraData={this.state}
                data={this.state.dataSource}
                renderItem={this.renderItem}
                keyExtractor={item => item.name}
                keyboardShouldPersistTaps="always"
                onEndThreshold={0}
            />


        </View>


    )
}

};

Product_Description logic Page - :

constructor(props) {
    console.log('constructer called');
    super(props)

    this.state = {

        dataSource: [],
        opacity: new Animated.Value(0)
    }
}

onLoad = () => {
    Animated.timing(this.state.opacity, {
        toValue: 1,
        duration: 500,
        useNativeDriver: true,
    }).start();
}

static navigationOptions = {

}


componentDidMount() {
    console.log("we are on Product_Description_Logic page componentDidMount function")
    const { navigation } = this.props;
    const id = navigation.getParam('id', 'NOT A id');

    console.log("here is name fetch data" + JSON.stringify(id))

    const url = 'http://192.168.0.105:8081/products/get/item_desc?item_id=' + id;

    fetch(url)
        .then((response) => response.json())
        .then((responseJson) => {
            this.setState({
                dataSource: responseJson.item_desc,


            }, console.log(responseJson.item_desc))
        })
        .catch((error) => {
            console.log(error);
        })
}
renderItem = ({ item,index }) => {
    console.log("-----------------------render item data Product_Description_Logic is---------------:: " + JSON.stringify(item))
    return (



        <View style={{ flexDirection: 'column', }}>

            <View style={{
                flex: 1,
                //height: responsiveHeight(50),
                //width: responsiveWidth(100),
                alignItems: 'center',

            }}>

                <Animated.Image
                    onLoad={this.onLoad}
                    {...this.props}
                    source={{ uri: item.item_url }}
                    style={{
                        opacity: this.state.opacity,
                        transform: [
                            {
                                scale: this.state.opacity.interpolate({
                                    inputRange: [0, 2],
                                    outputRange: [0.85, 1]
                                })
                            }],
                        width: responsiveHeight(35),
                        flex: 1,
                        height: responsiveHeight(25),
                        marginTop: responsiveHeight(3),
                        alignItems: 'center'
                    }}>

                </Animated.Image>
            </View>


            <View style={{ flex: 1 }}>


                <View style={{ flexDirection: 'row' }}>

                    <Text style={{ fontSize: responsiveFontSize(1.6), color: 'black', }}> Price : {item.price} </Text>


                    <TouchableWithoutFeedback>
                        <View style={{
                            alignItems: "center",
                            justifyContent:'center',
                            padding: responsiveHeight(0.5),

                            backgroundColor: '#ffab40',
                            marginHorizontal: responsiveHeight(8),
                            height: responsiveHeight(4.5),
                            width: responsiveWidth(30),
                            borderRadius: responsiveHeight(1)

                        }}>
                            <Text style={{ color: '#000000', fontSize: responsiveFontSize(1.8), justifyContent: 'flex-end', }}>Add to Cart</Text>
                        </View>
                    </TouchableWithoutFeedback>


                </View>




                <Text style={{
                    fontSize: responsiveFontSize(2),
                    color: '#000000',
                    //marginHorizontal: responsiveHeight(1)
                }}>{this.state.description}</Text>
                <Text style={{ fontSize: responsiveFontSize(1.7), color: '#000000', }}> available:  {item.available} </Text>


            </View>




            <View style={{ margin: responsiveHeight(1), }} >
                <Text style={{ fontSize: responsiveFontSize(2), color: 'green', }}>{item.available} </Text>
                <Text style={{ fontSize: responsiveFontSize(2), color: '#000000', }}>Quantity: 5 </Text>

            </View>


            <Text style={{ fontSize: responsiveFontSize(2), color: '#000000', margin: responsiveHeight(1) }}>About this item </Text>

            <View style={{ borderWidth: responsiveHeight(0.1), margin: responsiveHeight(2), borderColor: 'gray' }}>
                <Text style={{ fontWeight: 'bold', color: '#000000', fontSize: responsiveHeight(2) }}>  Features and details: </Text>
                <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1) }}> Graded, sorted and premium quality fruits </Text>
                <Text style={{ fontWeight: 'bold', color: '#000000', fontSize: responsiveHeight(2) }}> Product Details: </Text>

                <View style={{ flexDirection: 'row' }}>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), fontWeight: 'bold' }}> Manufacturer:</Text>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), }}>Fresh</Text>


                </View>
                <View style={{ flexDirection: 'row' }}>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), fontWeight: 'bold' }}> Item Part Number:</Text>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), }}>Apple_163</Text>
                </View>
                <View style={{ flexDirection: 'row' }}>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), fontWeight: 'bold' }}> ASIN:</Text>
                    <Text style={{ fontSize: responsiveHeight(2), color: '#000000', marginHorizontal: responsiveHeight(1), }}>vhajgdgvhjdjhd</Text>
                </View>

                <View style={{ borderBottomColor: 'gray', borderBottomWidth: responsiveHeight(0.1) }} />

                <Text style={{ fontWeight: 'bold', color: '#000000', fontSize: responsiveHeight(2), marginHorizontal: responsiveHeight(1) }}>Description: </Text>
                <Text style={{ color: '#000000', fontSize: responsiveHeight(1.8), marginHorizontal: responsiveHeight(1) }}>
                    {item.description}  </Text>

                <View style={{ borderBottomColor: 'gray' }} />
                <Text style={{ fontWeight: 'bold', color: '#000000', fontSize: responsiveHeight(2) }}> Important Information: </Text>

                <Text style={{ color: '#000000', fontSize: responsiveHeight(1.8), marginHorizontal: responsiveHeight(1) }}>
                    {item.imp_info}
                </Text>



                <TouchableWithoutFeedback>
                    <View style={{
                        alignItems: 'center',
                        padding: responsiveHeight(1),
                        backgroundColor: '#ffab40',
                        margin: responsiveHeight(5),
                        borderRadius: responsiveHeight(1)
                    }}>
                        <Text style={{ color: '#000000', fontSize: responsiveFontSize(1.8) }}>Continue Shopping</Text>
                    </View>
                </TouchableWithoutFeedback>



            </View>




        </View>




    );
}





render() {
    const { navigate } = this.props.navigation;
    const { navigation } = this.props;
    const id = navigation.getParam('id', 'not an valid id');

    console.log("this is prodcuctionDescription Render Fun" + JSON.stringify(id))


    return (

        <View>

            <FlatList
                data={this.state.dataSource}


                renderItem={this.renderItem}

                keyExtractor={item => item.name}

                onEndThreshold={0}


            />



        </View>




    )
}

};

1 个答案:

答案 0 :(得分:0)

遇到了同样的问题,并从@ValdaXD得到了修复。让我逐字引用他

它可能不是平面列表,因为它只能处理一项...可能是数据

某些API为多个数据Ex:[{1...},{2...},{3...}]返回json数组,并且faltlist组件很好地接收了该数组。但是,当仅请求一项时,api将返回一个单独的json Ex:{1...},而faltlist仅接受一个json数组,而不是一个单独的json ...

为此,您可以使用验证器函数,该函数将检查数据是数组还是单个json,并在将其用作平面列表数据之前对其进行调用。如果您同时放置了一个项目组或单个项目的响应,将会很有帮助

formatJSON(data){
    var result = []
    if(!Array.isArray(data)){//if is not an array
        result.push(data) // push it as the first item of an array
    }else{
        result=data
    }

    return result
}

已将其添加到您的抓取中

componentDidMount(){     console.log(“我们在Product_Description_Logic页面上的componentDidMount函数上”)     const {navigation} = this.props;     const id = navigation.getParam('id','NOT A id');

console.log("here is name fetch data" + JSON.stringify(id))

const url = 'http://192.168.0.105:8081/products/get/item_desc?item_id=' + id;

fetch(url)
    .then((response) => response.json())
    .then((responseJson) => {
        this.setState({
            dataSource: this.formatJSON(responseJson.item_desc),


        }, console.log(responseJson.item_desc))
    })
    .catch((error) => {
        console.log(error);
    })
 }

这个技巧对我有用