React Native:循环获取products数组imageUri转Base64后值为undefined问题
遍历产品数组生成Base64图片URI时出现全undefined问题
我尝试遍历products数组中的每个imageUri,将其编码为Base64后拼接成图片URI字符串,存入数组后传递给ProductList组件(该组件用div构建用于生成PDF)。但EditDocument.jsx和ProductList.jsx的控制台日志均显示img数组元素全为undefined。
控制台日志输出
EditDocument.jsx 日志代码
console.log("ED IMG2:", img); for (let i = 0; i < img.length; i++) { console.log("ED IMGS:", img.imageUri); }
日志结果
ED IMG2: Array [undefined, undefined, undefined,] ED IMGS: Array [undefined, undefined, undefined,]
ProductList.jsx 日志结果
PROD LIST IMG: Array [undefined, undefined, undefined,]
相关代码
EditDocument.jsx 核心代码
let img = []; for (let i = 0; i < data?.products?.length; i++) { try { if (data?.products) { const bloc = await FileSystem.readAsStringAsync(data.products.imageUri, { encoding: FileSystem.EncodingType.Base64, }) img = "data:image/png;base64," + bloc; console.log("ED IMG:", img); } } catch (error) { console.log(error); } } img.push(img[i]); } console.log("ED IMG2:", img); for (let i = 0; i < img.length; i++) { console.log("ED IMGS:", img.imageUri); }
ProductList.jsx 核心代码
const ProductList = ({ products, language, img }) => { return ( console.log("PROD LIST IMG:", img), <> <div style={{ width: "100%", marginBottom: 30 }}> <div className="tr"> <div className="th col1">#</div> <div className="th col2">{t("PRODUCT", { lng: language })}</div> <div className="th col3">{t("DESCRIPTION", { lng: language })}</div> <div className="th col4">{t("N°", { lng: language })}</div> <div className="th col5">{t("PRICE", { lng: language })}</div> <div className="th col6">{t("VAT", { lng: language })}</div> <div className="th col7">{t("TOTAL", { lng: language })}</div> </div> {products?.map((product, index) => ( console.log("PROD LIST IMG:", img), <div key={index} className="tr no-break"> {/* <div className="td col1">{index + 1}</div> */} {img ? ( console.log("PROD2 LIST IMG:", img.length), img.map(function (imageUri, index) { return ( <div key={index} className="td col1"> <img src={imageUri} style={styles.image} /> </div> ); }) ) : ( <div className="td col1">{index + 1}</div> )} <div className="td col2">{product.name}</div>
问题分析与修复
核心问题点
- 数组引用被覆盖:循环中直接将
img从数组赋值为字符串(img = "data:image/png;base64," + bloc;),彻底丢失了原数组的引用,后续操作完全错误。 - 数组元素访问错误:应该取
data.products[i].imageUri(当前循环项的图片地址),而非data.products.imageUri(访问数组本身的imageUri属性,不存在)。 - 循环外的无效代码:
img.push(img[i]);写在循环外部,此时i已超出数组长度,img[i]必然是undefined,还多了一个冗余的闭合大括号。 - 日志输出错误:遍历数组时用
img.imageUri是错误写法,应该用img[i]访问对应索引的元素。
修复后的EditDocument.jsx代码
let img = []; // 确保products存在再执行循环 if (data?.products) { for (let i = 0; i < data.products.length; i++) { try { const currentProduct = data.products[i]; // 先判断当前产品的imageUri是否存在 if (currentProduct?.imageUri) { const bloc = await FileSystem.readAsStringAsync(currentProduct.imageUri, { encoding: FileSystem.EncodingType.Base64, }); // 将拼接好的Base64 URI push进数组,而非覆盖数组 img.push(`data:image/png;base64,${bloc}`); console.log("ED IMG:", img[i]); } else { // 无图片时push占位值,保证数组长度与products一致 img.push(null); } } catch (error) { console.log("图片编码错误:", error); // 出错时也push占位值,避免数组长度不匹配 img.push(null); } } } console.log("ED IMG2:", img); // 正确遍历数组元素 for (let i = 0; i < img.length; i++) { console.log("ED IMGS:", img[i]); }
ProductList.jsx优化建议
渲染时通过索引匹配对应产品的图片,避免重复渲染所有图片:
const ProductList = ({ products, language, img }) => { console.log("PROD LIST IMG:", img); return ( <> <div style={{ width: "100%", marginBottom: 30 }}> <div className="tr"> <div className="th col1">#</div> <div className="th col2">{t("PRODUCT", { lng: language })}</div> <div className="th col3">{t("DESCRIPTION", { lng: language })}</div> <div className="th col4">{t("N°", { lng: language })}</div> <div className="th col5">{t("PRICE", { lng: language })}</div> <div className="th col6">{t("VAT", { lng: language })}</div> <div className="th col7">{t("TOTAL", { lng: language })}</div> </div> {products?.map((product, index) => ( <div key={index} className="tr no-break"> {/* 根据索引匹配当前产品对应的图片 */} {img?.[index] ? ( <div className="td col1"> <img src={img[index]} style={styles.image} /> </div> ) : ( <div className="td col1">{index + 1}</div> )} <div className="td col2">{product.name}</div> {/* 剩余渲染代码 */} </div> ))} </div> </> ); };
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

