【问题标题】:How do I map over two arrays at the same time in react native?如何在本机反应中同时映射两个数组?
【发布时间】:2018-10-11 07:35:34
【问题描述】:

如何在 react native 中映射两个不同的数组?就我而言,我正在从服务器获取响应并对其进行映射。还有另一个名为images 的数组,我想将它与从服务器获取的响应一起列出。但是第二个映射在第一个映射中循环。我如何将它与第一个分开?以下是我的代码。

示例代码

<ScrollView>
  {this.state.workers.map(a =>
    <CardSection>
      <TouchableOpacity onPress={() => this.popupDialog.show()}>
        <View style={{ marginTop: 10, marginLeft:120}}>
          {images.map(b =>
            <Image
              style={{ height: 100, width: 100 }}
              source={{ uri: b.image }}
             />
           )}
           <Text style={{marginLeft:20, fontSize:20}}>{a.work_type}</Text>
         </View>
       </TouchableOpacity>
     </CardSection>
   )}

workers 数组是我从服务器获取的 json 响应。images 数组如下所示

export const images = [
  {
    image:'http://localhost:3000/Images/carpenter.png',
    text:'hello'
  },
  {
    image:'http://localhost:3000/Images/electrician.png',
    text:'hii'
  },
]

这也是workers 数组的样子

更新

 [
        {
            "sl.no": 1,
            "worker_id": "wr_1",
            "work_type": "carpenter",
            "phone_num": "3456789243"
        },
        {
            "sl.no": 2,
            "worker_id": "wr_2",
            "work_type": "electrician",
            "phone_num": "345221344"
        },
        {
            "sl.no": 3,
            "worker_id": "wr_3",
            "work_type": "plumber",
            "phone_num": "8976545677"
        }
    ]

【问题讨论】:

  • 上面粘贴的代码有什么问题?
  • 您是要为每个工人渲染图像组件还是只渲染一次?有点迷茫
  • this.state.workers.map((a, index) =&gt; { let b = images[index]; return ... })

标签: javascript react-native jsx array-map


【解决方案1】:

您可以简单地将其移动到第一张地图上方并保存结果:

render() {
  const imagesToRender = images.map(b => {
    return (
      <Image
        style={{ height: 100, width: 100 }}
        source={{ uri: b.image }}
      />
    );
  });

  return (
    <ScrollView>
      {this.state.workers.map(a =>
        <CardSection>
          <TouchableOpacity onPress={() => this.popupDialog.show()}>
            <View style={{ marginTop: 10, marginLeft:120}}>
              {imagesToRender}
              <Text style={{marginLeft:20, fontSize:20}}>{a.work_type}</Text>
            </View>
          </TouchableOpacity>
        </CardSection>
      )}
    </ScrollView>
  );
}

另外,不要忘记将 key 属性添加到每个 Image 和每个 CardSection

【讨论】:

  • 这个OP原码没问题。这个答案只是通过将嵌套映射移动到一个单独的常量来重构它。
  • @FirmanWijaya 这就是我对 OP 要求的理解:如何避免在外部 .map 的每次迭代中都执行内部 .map
  • @Firman Wijaya 我已经尝试过您的代码,但没有显示图像,请检查i.stack.imgur.com/AAnI7.png
  • @Firman Wijaya 问题是访问本地主机图像我用我的 ip 更改了它。但是图像在一张卡片中重复检查这个i.stack.imgur.com/ozxCH.png
  • @anu 然后您可以使用索引访问images 数组,假设服务器响应(workers)与images 数组匹配。请检查我的答案
【解决方案2】:

您可以轻松使用性能更好的 flatlist

import React, { Component } from "react";
import { View, FlatList, TouchableOpacity, Image, Text } from "react-native";

const workers = [
    { id: 1, name: 'Nima', images: [{ image: 'https://www.lens-rumors.com/wp-content/uploads/2014/10/Nikon-AF-S-DX-Nikkor-18-140mm-f3.5-5.6G-ED-VR-sample-images1.jpg', text: 'hello' },{ image: 'https://www.lens-rumors.com/wp-content/uploads/2014/10/Nikon-AF-S-DX-Nikkor-18-140mm-f3.5-5.6G-ED-VR-sample-images1.jpg', text: 'hello' },{ image: 'https://www.lens-rumors.com/wp-content/uploads/2014/10/Nikon-AF-S-DX-Nikkor-18-140mm-f3.5-5.6G-ED-VR-sample-images1.jpg', text: 'hello' },{ image: 'https://www.lens-rumors.com/wp-content/uploads/2014/10/Nikon-AF-S-DX-Nikkor-18-140mm-f3.5-5.6G-ED-VR-sample-images1.jpg', text: 'hello' }] },
    { id: 2, name: 'Mike', images: [{ image: 'https://www.dike.lib.ia.us/images/sample-1.jpg/image', text: 'goodby' },{ image: 'https://www.dike.lib.ia.us/images/sample-1.jpg/image', text: 'goodby' },{ image: 'https://www.dike.lib.ia.us/images/sample-1.jpg/image', text: 'goodby' },{ image: 'https://www.dike.lib.ia.us/images/sample-1.jpg/image', text: 'goodby' },] },
]

class Test extends Component {
    constructor(props) {
        super(props);

        this.state = {
            workers: workers
        };
    }

    _renderItem = ({ item }) => {
        console.log(item);
        return (
            <View style={{ flex: 1 }}>
                <TouchableOpacity>
                    <View style={{ marginTop: 10, marginLeft: 120 }}>
                        {item.images.map((b, index) => {
                            console.log(b.image);
                            return (
                                <View key={index}>
                                    <Image
                                        style={{ height: 100, width: 100 }}
                                        source={{ uri: b.image }}
                                    />
                                    <Text
                                        style={{ marginLeft: 20, fontSize: 20, color: "black" }}
                                    >
                                        {b.text}
                                    </Text>
                                </View>
                            );
                        })}
                        <Text style={{ marginLeft: 20, fontSize: 20, color: "black" }}>
                            {item.name}
                        </Text>
                    </View>
                </TouchableOpacity>
            </View>
        );
    };

    _keyExtractor = (item, index) => item.id.toString();

    render() {
        return (
            <FlatList
                data={this.state.workers}
                extraData={this.state}
                keyExtractor={this._keyExtractor}
                renderItem={this._renderItem}
            />
        );
    }
}

export default Test;

【讨论】:

    【解决方案3】:

    如果图像没有加载,可能是因为您将错误的属性传递给&lt;Image /&gt; 组件。查找 &lt;Image /&gt; 组件的文档或将其替换为 &lt;img /&gt; 并将图像的 url 字符串传递给 src 属性。

    getImageUri(worker) {
      // Decide which image to return for a certain type of worker
      // For more workers and images, change the following logic
      if(worker.work_type == 'carpenter') {
        return images[0].image;
      } else if(worker.work_type == 'electrician') {
        return images[1].image;
      } else {
        return '';
      }
    }
    
    render() {
    ...
    <ScrollView>
      {this.state.workers.map((a, index) =>
        <CardSection>
          <TouchableOpacity onPress={() => this.popupDialog.show()}>
            <View style={{ marginTop: 10, marginLeft:120}}>
                <Image
                  style={{ height: 100, width: 100 }}
                  source={{ uri: this.getImageUri(a)}}
                 />
               <Text style={{marginLeft:20, fontSize:20}}>{a.work_type}</Text>
             </View>
           </TouchableOpacity>
         </CardSection>
       )}
    </ScrollView>
    ...
    }
    

    【讨论】:

    • 我在哪里编写映射图像数组的代码?而且我在此代码上遇到错误。
    • @anu 您不映射 images 数组,而是使用数组索引访问它们。如果workers 数组与images 数组匹配,您可以简单地通过索引访问images 数组。
    • @FirmanWijaya 如果他的数组中有多个图像怎么办?
    • @FirmanWijaya 我无法读取未定义的属性图像。
    • @anu:这意味着workers 数组中的元素比images 数组中的元素多。然后只需使用三元运算符检查要使用的图像。答案已更新
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多