You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native电影API数据无法显示及TypeError问题求助

解决React Native中OMDb API数据无法显示及TypeError问题

我来帮你排查并解决这两个核心问题——控制台能打印数据但界面不展示,还有那个烦人的TypeError: undefined is not an object (evaluating 'state.results.map')错误,咱们一步步来梳理:

问题1:界面不显示数据——map函数未返回JSX元素

你在ScrollView里的state.results.map写法有个小疏漏:箭头函数用了大括号{}但没有显式返回JSX元素,导致React Native渲染时拿不到要展示的内容,自然就看不到数据了。

修复方式

两种可选方案,选你习惯的就行:

// 方案1:用小括号包裹JSX,自动返回元素
{state.results.map(result => (
  <View key={result.imdbID} style={styles.result}>
    <Text>{result.Title}</Text>
  </View>
))}

// 方案2:显式添加return关键字
{state.results.map(result => {
  return (
    <View key={result.imdbID} style={styles.result}>
      <Text>{result.Title}</Text>
    </View>
  )
})}

问题2:TypeError——results可能变为undefined

你的初始state.results是数组,但当API请求返回的data.Search不存在时(比如搜索不到电影、API返回错误,或者URL参数格式有误),let results = data.Search会把results设为undefined,之后setState会把state.results变成undefined,调用map就会触发类型错误。

修复方式

  1. 给Search设置默认空数组:确保results永远是数组类型,避免map报错
  2. 修复URL转义字符:把代码里的&amp;换成真实的&(&amp;是HTML实体,axios请求时会被当成字符串的一部分,导致API参数解析错误)
  3. 添加错误捕获:处理网络问题或API返回失败的情况,避免程序崩溃

具体修改如下:

const search = () => {
  axios(apiurl + "&s=" + state.s)
    .then(({data})=>{
      // 给Search设置默认空数组,防止undefined
      let results = data.Search || []
      console.log(results)
      setState(prevState =>{
        return {...prevState,results:results}
      })
    })
    // 新增错误捕获逻辑
    .catch(err => {
      console.error("请求出错:", err)
      setState(prevState => ({...prevState, results: []}))
    })
}

// 同时修复API URL
const apiurl = "http://www.omdbapi.com/?i=tt3896198&apikey=4c0e830";

修改后的完整代码

import React ,{ useState }from 'react';
import axios from'axios';
import { StyleSheet, Text, View ,ScrollView,TextInput} from 'react-native';

export default function App() {
  // 修复URL中的转义字符
  const apiurl = "http://www.omdbapi.com/?i=tt3896198&apikey=4c0e830";
  const [state,setState] = useState({ s:'Enter A Movie...', results:[], selected:{} });

  const search = () => {
    axios(apiurl + "&s=" + state.s)
      .then(({data})=>{
        // 确保results始终是数组
        let results = data.Search || []
        console.log(results)
        setState(prevState =>{
          return {...prevState,results:results}
        })
      })
      // 处理请求错误
      .catch(err => {
        console.error("请求失败:", err)
        setState(prevState => ({...prevState, results: []}))
      })
  }

  return (
    <View style={styles.container}>
      <Text style={styles.Header}>Movie DataBase</Text>
      <TextInput 
        style={styles.searchBar} 
        onChangeText={text => setState(prevState =>{
          return{...prevState, s: text}
        })} 
        onSubmitEditing={search} 
        value={state.s} 
      />
      <ScrollView style={styles.results}>
        {/* 用小括号自动返回JSX元素 */}
        {state.results.map(result => (
          <View key={result.imdbID} style={styles.result}>
            <Text>{result.Title}</Text>
          </View>
        ))}
      </ScrollView>
    </View>
  );
}

// 补充示例样式(你之前的代码未包含,可根据需求调整)
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#fff',
  },
  Header: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 16,
    textAlign: 'center',
  },
  searchBar: {
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8,
    padding: 8,
    marginBottom: 16,
  },
  results: {
    flex: 1,
  },
  result: {
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
});

现在再测试一下:输入电影名提交后,数据应该能正常显示在界面上;即使搜索不到内容或者请求失败,也不会再触发那个TypeError了。

内容的提问来源于stack exchange,提问作者Marlo Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:42:30