React Native调用Drupal 9 API动态获取图片报错求助
问题分析与解决方案
核心错误点
遍历产品列表时出现「找不到relationships」的报错,根源是代码错误使用了producto[0].relationships——producto是map循环中的单个产品对象,而非数组,加[0]会导致访问undefined的relationships属性,直接触发报错。
完整修复步骤
1. 修正遍历中的对象访问
将Image组件source部分的producto[0].relationships改为producto.relationships。
2. 正确获取Drupal图片URL
Drupal JSON:API返回的图片ID只是资源标识,不能直接作为Image的source,需通过以下方式获取实际图片URL:
方式一:请求产品时关联获取图片数据(推荐)
在API请求中添加include=field_imagen参数,让Drupal一次性返回产品和关联的图片数据,避免多次请求。修改后的请求URL为:
const URL_BASE = 'https://abarrotes.msalazar.dev/jsonapi/node/productos?include=field_imagen'
之后在遍历中,通过产品的图片ID从返回的included数组中匹配对应图片对象,提取图片URL。
方式二:单独请求图片资源(不推荐,增加请求次数)
如果不使用include,需用图片ID构建请求地址单独获取URL,但会为每个产品发起额外请求,影响性能。
3. 优化状态初始化
将productos的初始状态从{}改为[],因为接口返回的response.data.data是数组,初始化为数组更符合数据结构逻辑。
修改后的完整代码
import React,{useEffect,useState} from 'react' import { Layout,Text,Card, Button } from "@ui-kitten/components"; import { StyleSheet,Image } from 'react-native'; import axios from 'axios'; // 添加include参数,关联获取图片数据 const URL_BASE = 'https://abarrotes.msalazar.dev/jsonapi/node/productos?include=field_imagen' const InventoryDairy = () => { // 初始化为数组,匹配接口返回的数据结构 const [productos, setProductos] = useState([]) const [included, setIncluded] = useState([]) const getDary = () => { axios.get(URL_BASE, { headers: { 'Content-Type': 'application/json' } }) .then(function (response) { setProductos(response.data.data) // 保存关联的图片数据 setIncluded(response.data.included) }) .catch(function (error) { console.log(error); }); } useEffect(()=> { getDary() },[]) // 封装函数:通过图片ID获取图片URL const getImageUrl = (imageId) => { const imageData = included.find(item => item.id === imageId) return imageData?.attributes?.uri?.url || '' } return ( <Layout> <Text style={styles.titleMain}>Inventario Lacteos</Text> { productos.map((producto,index)=>{ // 安全获取当前产品的图片ID const imageId = producto.relationships?.field_imagen?.data?.id // 获取完整图片URL const imageUrl = getImageUrl(imageId) return( <Card key={index} style={styles.card} status='primary'> <Layout style={styles.productsInformation}> <Text style={styles.title}><Text>Proveedor:</Text> {producto.attributes.field_proveedor}</Text> <Text style={styles.title}>{producto.attributes.title}</Text> <Text style={styles.title}><Text>Precio:</Text> ${producto.attributes.field_precio_venta}</Text> </Layout> {imageUrl ? ( <Layout style={styles.productsPhoto}> <Image source={{ uri: `https://abarrotes.msalazar.dev${imageUrl}` }} style={{ width: 100, height: 100 }} // 必须设置图片尺寸 /> </Layout> ) : null} <Text style={styles.title}><Text>Inventario :</Text> {producto.attributes.field_inventory}</Text> </Card> ) }) } </Layout> ) } const styles = StyleSheet.create({ titleMain: { fontSize: 20, fontWeight: 'bold', padding: 10, }, card: { margin: 10, padding: 10, }, productsInformation: { marginBottom: 10, }, title: { fontSize: 16, marginBottom: 5, }, productsPhoto: { marginBottom: 10, } }) export default InventoryDairy
额外说明
- Image组件必须设置宽高样式,否则图片无法正常显示。
- 使用可选链操作符
?.可避免因属性不存在引发的报错,比如producto.relationships?.field_imagen?.data?.id。
内容的提问来源于stack exchange,提问作者Julián Ontiveros Ramírez
相关产品推荐
相关产品推荐

