2016-11-29 65 views
1

我正在为一些反应基础(主要是数据流和jsx语法)苦苦挣扎,对于noob问题感到抱歉。使用map函数反应并将数据解析到子组件

我有两个json,我正在Main.js中链接api调用,数据然后传递到SensorList.js。在这个组件中,我有一个呈现传感器列表的函数,每个Sensor.js都将其键设置为json中指定的id,并根据json中的数据设置其props。

目前我能够抓住每个传感器的第一个对应的数据片,并将其传递给相关的子组件。我需要将相应数据的整个数组传递给子组件Graph.js,目前我的map函数仅抓取每个数组中的第一个元素。

我的问题是我如何实际传递每个传感器的值和时间数据的整个数组到它的子图组件?

在此先感谢。

sensors.json

[ 
    { 
    "id": "46c634d04cc2fb4a4ee0f1596c5330328130ff80", 
    "name": "external" 
    }, 
{ 
    "id": "d823cb4204c9715f5c811feaabeea45ce06736a0", 
    "name": "office" 
    }, 
{ 
    "id": "437b3687100bcb77959a5fb6d0351b41972b1173", 
    "name": "common room" 
    } 
] 

data.json样本

[ 
    { 
    "sensorId": "437b3687100bcb77959a5fb6d0351b41972b1173", 
    "time": 1472120033, 
    "value": 25.3 
    }, 
{ 
    "sensorId": "437b3687100bcb77959a5fb6d0351b41972b1173", 
    "time": 1472119853, 
    "value": 25.1 
}, 
{ 
    "sensorId": "437b3687100bcb77959a5fb6d0351b41972b1173", 
    "time": 1472119673, 
    "value": 25.1 
}, 

SensorList.js

var SensorList = React.createClass({ 
    render: function() { 
    var {data, sensors} = this.props; 

    var renderSensors =() => { 
     return sensors.map((sensor) => { 
     return <Sensor key={sensor.id} name={sensor.name} value={data.get(sensor.id)}/> 
     }); 
    }; 

    return (
     <div> 
     {renderSensors()} 
     </div> 
    ); 
    } 
}); 

Main.js

var Main = React.createClass({ 
    getInitialState: function() { 
    return { 
     sensors: [], 
     sensorsData: [] 
    }; 
    }, 

    componentDidMount: function() { 
    var _this = this; 
    this.serverRequest = 
     axios 
     .get("http://localhost:3000/sensors.json") 
     .then(function(result) { 
      _this.setState({ 
      sensors: result.data 
      }); 
     }) 
     axios 
     .get("http://localhost:3000/data.json") 
     .then(function(result) { 
      var sensorDataToId = new Map(); 
      for(var i = 0; i < result.length; i++) { 
      var datum = result[i]; 
      var sensorId = datum.sensorId; 
      if (sensorDataToId.get(sensorId) === undefined) { 
       sensorDataToId.set(sensorId, []); 
      } 

      sensorDataToId.get(sensorId).push(datum) 
      } 
      _this.setState({ 
      sensorsData: result.data 
      }); 
     }) 
    }, 

    componentWillUnmount: function() { 
    this.serverRequest.abort(); 
    }, 

    render: function() { 
    var {sensors, sensorsData} = this.state; 

    return (
     <div className="sensorList"> 
     <SensorList sensors={sensors} data={sensorsData}/> 
     </div> 
    ); 
    } 
}); 

回答

0

首先改变你的数据。取数据列表并将其变成传感器ID到数据阵列的映射(这与反应无关,并且可能应该在最初处理AJAX响应时进行)。然后在您的sensors.map,只是通过sensorDataToId.get(sensor.id)

整形可能看起来像:

var sensorDataToId = new Map(); 
for(var i = 0; i < data.length; i++) { 
    var datum = data[i]; 
    var sensorId = datum.sensorId; 
    if (sensorDataToId.get(sensorId) === undefined) { 
    sensorDataToId.set(sensorId, []); 
    } 

    sensorDataToId.get(sensorId).push(datum) 
} 

更新您的setState呼叫

_this.setState({sensorsData: sensorDataToId}); 

那么你sensors.map

var renderSensors =() => { 
    return sensors.map((sensor) => { 
    return <Sensor key={sensor.id} name={sensor.name} value={data.get(sensor.id)}/> 
    }); 
}; 
+0

感谢您的回复。我已经更新了我的帖子,并且包含了我正在进行api调用的组件。你是说在第二个响应中重塑_this.setState中的数据吗? –

+0

@LukeAveil在该回调中,但在setState之前。我会用重新调整的数据调用setState。 –

+0

我已经根据上面更新了回调,一切似乎都仍在工作。我有点不确定你的意思是把'sensorDataToId.get(sensor.id)'放在sensors.map中?你的意思是现在删除dataList.map和if语句并将其替换为'sensorDataToId.get(sensor.id)'?干杯。 –

0

怎么样你遍历一个列表并使用t他'找到'方法来查找其他属性。

var renderSensors =() => { 
    return(
    sensors.map((sensor) => { 
     var dataItem = dataList.find((data)=>{ 
      return (data.sensorId === sensor.id) 
     }) 
    return(
     <Sensor key={dataItem.sensorId} name={sensor.name} value={dataItem.value} time={dataItem.time}/>)  
    }) 
) 
}; 
+0

使用下划线功能可能有更多的方法来做到这一点。 :) –

+0

谢谢@Amoolya。不幸的是,这似乎并不奏效:/ –

+0

@LukeAveil嗨,我错过了rendorSensors()中最外面的返回块。已经做了编辑。你能再试一次吗? –