【问题标题】:Creating Search function with React Native for Zomato API使用 React Native 为 Zomato API 创建搜索功能
【发布时间】:2020-04-18 21:41:09
【问题描述】:

我不熟悉将 API 与 React Native 一起使用,我已经弄清楚了一些事情,但我现在要做的是创建一个搜索功能。到目前为止,我已经尝试了一些事情,但要么没有调用该函数,要么我收到关于该函数作为对象调用的错误。另外,我正在使用 axios 进行此 API 调用

这是我到目前为止所得到的。

export default class CategoryScreen extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [],
            isVisible: true,
            city: '280',
            isLoading: true,
            search: ''
        }
    }

    async componentDidMount() {
        try {
            const id = this.props.navigation.state.params.category;
            const city = this.state.city;

            const result = await axios.request({
                method: 'get',
                url: `https://developers.zomato.com/api/v2.1/search?city_id=${city}&category=${id}`,
                headers: {
                    'Content-Type': 'application/json',
                    'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
                }
            });
            this.setState({ data: result.data.restaurants });
        } catch (err) {
            console.log(err);
        } finally {
            this.setState({ isLoading: false });
        }
    }

    updateSearch = search => {
        this.setState({ search });
    };

    searchReq = () => {
        axios.request({
            method: 'get',
            url: `https://developers.zomato.com/api/v2.1/search?city_id=${city}&q${search}&category=${id}`,
            header: {
                'Content-Type': 'application/json',
                'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
            }
        });
        this.setState({ data: result.data.restaurants });
    }

    render() {
        const { search } = this.state;
        return (
            <SearchBar
                placeholder="Type Here..."
                onChangeText={this.updateSearch}
                onSubmitEditing={this.searchReq}
                value={search}
            />
        )
    }
}

如果有更高级的方法,我愿意学习新事物,我只想完成我想做的事情。另外,我知道如果我当前的方法有效,如果用户在两者之间添加一个空格,它仍然会导致问题,所以我非常愿意学习新的和更高级的方法

这里是世博小吃https://snack.expo.io/SJoIr8u1I

【问题讨论】:

  • 你能分享一下世博小吃中的代码吗?生病检查那里
  • @CoolMAn 我无法运行您的博览会小吃,有很多错误。在修复它们并将您的 LOGO 指向我能够运行的唯一图像资产之后。第 ~27 行:this.props.navigation 未定义,因此在尝试访问 navigate 时失败。不过你不要打电话给this.navigatesnack.expo.io/ryiOgvuJI
  • @DrewReese 对此我深表歉意。我使用导航转到另一个屏幕,但是我一定已经删除了有关它的其余代码并忘记了这个。
  • @CoolMAn 啊,在那种情况下,这一切似乎都与注释掉的一样。 (修复其他错误后)
  • @DrewReese 搜索功能有效并显示与搜索相关的结果?它仍然不适合我:\

标签: reactjs react-native axios zomato-api


【解决方案1】:

我注意到你的搜索功能有几个错误。

  1. 你需要得到citysearchid不在searchReq()中的值
  2. 您需要先获取result.data.restaurants 值,然后再将其分配给data: result.data.restaurants

由于您已经分配了this.setState({ search }),因此我在searchReq() 中得到了该值,如下所示,

searchReq = async () => {
    try {
        const result = await axios.request({
            method: 'get',
            url: `https://developers.zomato.com/api/v2.1/search?city_id=280&q${this.state.search}&category=11`,
            headers: {
                'Content-Type': 'application/json',
                'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
            }
        });
        this.setState({ data: result.data.restaurants });
    } catch (error) {
        this.setState({ data: [] });
        console.log(error);
    }
}

所以完整的源代码会是这样的

import React, { Component } from 'react';
import {
    View,
    Text,
    FlatList,
    StyleSheet,
    TouchableOpacity,
    Dimensions,
    ActivityIndicator,
} from 'react-native';
import { Card, Image, SearchBar, Icon } from 'react-native-elements';
import Logo from '../assets/Logo.png'
import axios from 'axios';

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

export default class CategoryScreen extends Component {

    constructor(props) {
        super(props);
        this.state = {
            data: [],
            isVisible: true,
            city: '280',
            isLoading: true,
            search: ''
        }
    }

    async componentDidMount() {
        try {
            const result = await axios.request({
                method: 'get',
                url: `https://developers.zomato.com/api/v2.1/search?city_id=280&category=11`,
                headers: {
                    'Content-Type': 'application/json',
                    'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
                }
            });
            this.setState({
                data: result.data.restaurants,
                isLoading: false
            });
        } catch (err) {
            this.setState({ isLoading: false });
            console.log(err);
        }
    }

    updateSearch = search => {
        this.setState({ search });
    };

    searchReq = async () => {
        try {
            const result = await axios.request({
                method: 'get',
                url: `https://developers.zomato.com/api/v2.1/search?city_id=280&q${this.state.search}&category=11`,
                headers: {
                    'Content-Type': 'application/json',
                    'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
                }
            });
            this.setState({ data: result.data.restaurants });
        } catch (error) {
            this.setState({ data: [] });
            console.log(error);
        }
    }

    render() {
        const { search } = this.state;
        return (
            <View>
                <View style={styles.header}>
                    <Image source={Logo} style={{ resizeMode: 'stretch', width: 50, height: 50, alignSelf: 'center', justifyContent: 'center', marginTop: 30 }} />
                    <Icon
                        raised
                        name='location'
                        type='octicon'
                        color='#f50'
                        onPress={() => this.setState({ isModalVisible: !this.state.isModalVisible })}
                        containerStyle={{ alignSelf: 'flex-end', marginRight: 20, marginTop: -60 }} />
                </View>
                <SearchBar
                    placeholder="Type Here..."
                    onChangeText={this.updateSearch}
                    onSubmitEditing={this.searchReq}
                    value={search}
                    inputStyle={{ backgroundColor: 'steelblue', color: 'white' }}
                    inputContainerStyle={{ backgroundColor: 'steelblue', fontColor: 'white' }}
                    containerStyle={{ backgroundColor: 'steelblue', borderBottomColor: 'transparent', borderTopColor: 'transparent' }}
                    placeholderTextColor='white'
                />
                {
                    this.state.isLoading ?
                        <View style={{ flex: 1, marginTop: 200 }}>
                            <ActivityIndicator style={{ color: 'red' }} />
                        </View> :
                        (
                            this.state.data.length == 0 ?
                                <View style={{ flex: 1, padding: 20, marginTop: 100 }}>
                                    <Text style={{ color: '#000', fontWeight: 'bold' }}>No restaurants from selected category</Text>
                                </View> :
                                <View style={{ flexDirection: 'column' }}>
                                    <FlatList
                                        keyExtractor={item => item.id}
                                        data={this.state.data}
                                        renderItem={({ item }) =>
                                            <TouchableOpacity onPress={() => console.log(item.restaurant.location.city)}>
                                                <Card style={{ width: SCREEN_WIDTH }}>
                                                    <Image style={{ width: SCREEN_WIDTH / 3, height: 130 }} resizeMode="stretch" source={{ uri: item.restaurant.thumb }} />
                                                    <Text style={{ color: '#000', fontWeight: 'bold' }}>{item.restaurant.name} </Text>
                                                </Card>
                                            </TouchableOpacity>
                                        }
                                    />
                                </View>
                        )
                }
            </View>
        )
    }
}

const styles = StyleSheet.create({
    header: {
        backgroundColor: '#ff4714',
        height: SCREEN_HEIGHT / 8,

    },
});

希望对你有所帮助。

【讨论】:

  • 所以,我试试这个,没有错误!但是结果不显示
  • @CoolMAn 确保您将正确的参数传递给搜索查询。
  • 我在函数中添加了一个console.log('check'),当我按下键盘上的回车键时,终端中什么也没有显示,可能函数没有被调用
  • @CoolMAn 你在哪里添加console.log('check')
  • searchReq 函数的try {} 部分中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 2020-04-22
  • 2021-12-07
  • 1970-01-01
相关资源
最近更新 更多