2017-11-14 1 views
0

반응 내에서 데이터 기반 렌더링에 JSON 매핑에 대해 노력하고 있습니다. 내가해야 할 일의 일부를 성취하는 것. 중첩 JSON이 필요합니다. 이 데이터를 매핑하려고하면 매핑 할 수없는 값으로 계속 실행됩니다. 특히 보간 된 div에 중첩 된 값을 전달하려고 시도 할 때 (mapObject.object.value)을 시도 할 때.API 호출에서 매핑 할 때 중첩 JSON 객체 검색

import React, { Component } from 'react'; 
import '../HeaderBar/HeaderBar.css'; 
import 'whatwg-fetch'; 

type StatusBarProps = {}; 
type StatusBarState = { 
    // tslint:disable-next-line:no-any 
    positionStatus: any; 
}; 

class StatusBar extends Component<StatusBarProps, StatusBarState> { 
    constructor() { 
     super(); 
     this.state = { 
      positionStatus: [] 
     }; 
    } 
    componentWillMount() { 
     // maps azimuth and elevation for all objects 
     fetch('http://localhost:5001/PositionComponent/').then(results => { 
      return results.json(); 
     }).then(data => { 
      let positionStatus = data.map((positioning) => { 
       return (
        <div className="temporary" key={positioning.key}>{positioning.Elevation.positionValue} : {positioning.Azimuth.positionValue}</div> 
       ); 
      }); 
      this.setState({ positionStatus: positionStatus }); 
     }); 
    } 
    render() { 
     return (
      <div className="location"> 
       <div className="col-xs-12"> 
        {this.state.positionStatus} 
       </div> 
      </div> 
     ); 
    } 
} 

export default StatusBar; 

관련 JSON 문제의 컨텍스트를 제공되었지만, 개발 속도를 위해 JSON.server에서 제공되는 :

JSON

{"PositionComponent": [ 
     { 
      "key": 0, 
      "Elevation": { 
       "positionValue": "1.11566", 
       "id": 0 
      } 
     }, 
     { 
      "key": 1, 
      "Azimuth": { 
       "positionValue": "1.145657", 
       "id": 1 
      } 
     } 
    ] 
} 

는 구성 요소를 반응한다. 문제는 내가 {positioning.Elevation.positionValue}을 호출하여 객체 자체에 레벨을 내려갈 수없는 Object {key: 0, Elevation: Object } Object { key: 1, Azimuth: Object }을 수신하고있는 것 같습니다. 제 질문은 이것을 어떻게 매핑하여 내부 객체 값을 고도와 방위각에 묶을 수 있습니까?

+0

'data.PositionComponent.map (...) '대신'data' 대신 매핑을 시도 했습니까? – mersocarlin

+0

@mersocarlin 전 아니지만, 지금 노력하고 있습니다. – jpearsonNode

+0

@mersocarlin 그것은 data.PositionComponent가 throw됩니다. 정의되지 않은 오류 – jpearsonNode

답변

2

가 주요 문제는 여기에 있습니다 :

{positioning.Elevation.positionValue}/{positioning.Azimuth.positionValue} 

당신이 그들 중 적어도 하나를 제공해야해야 네가 움켜 쥐고 싶은 중첩 된 키를 가지고있는 각 객체마다 다른 키를 가지고 있다는 것을.
조건부로 액세스하여 기존의 Elevation 또는 Azimuth을 확인하고 액세스 할 수 있습니다.
이 방법의 단점은 새 키를 추가 할 때 다른 조건을 추가해야한다는 것입니다. 따라서 좀 더 일반적인 접근 방식을 원할 수 있습니다.

Object.entries.map부터 keys까지는 positionValue을 반환 할 수 있습니다. 특정 키가 그것을 보유하고 있지 않다면, 정의되지 않은 값이 평가 될 것입니다. map은 그것을 무시하고 반환하지 않을 것입니다. 이 같은
뭔가 :

Object.entries(positioning).map(([key, value]) => { 
    return positioning[key].positionValue; 
}) 

나는 다른 방법을 밖으로 렌더링 논리를 꺼내 실 거예요 상태에서 마크 업을 저장하는 것입니다.
변경하려는 것 또 다른 것은 여기 avoid the use of fetching or side effects in componentWillMount

입니다 코드의 실행 예 (내가 서버에 데이터를 가지고 있지 않는 한 내가 가져 오기 사용하지 않은)

const dataFromServer = [ 
 
    { 
 
    key: 0, 
 
    Elevation: { 
 
     positionValue: "1.11566", 
 
     id: 0 
 
    } 
 
    }, 
 
    { 
 
    key: 1, 
 
    Azimuth: { 
 
     positionValue: "1.145657", 
 
     id: 1 
 
    } 
 
    } 
 
]; 
 

 
class StatusBar extends React.Component { 
 
    constructor() { 
 
    super(); 
 
    this.state = { 
 
     positionStatus: [] 
 
    }; 
 
    } 
 

 
    componentDidMount() { 
 
    let positionStatus = dataFromServer; 
 
    this.setState({ positionStatus: positionStatus }); 
 
    } 
 

 
    renderPositionstatus =() => { 
 
    const { positionStatus } = this.state; 
 
    return (
 
     <div> 
 
     {positionStatus.map(positioning => { 
 
      return (
 
      <div className="temporary" key={positioning.key}> 
 
       {Object.entries(positioning).map(([key, value]) => { 
 
       return positioning[key].positionValue; 
 
       })} 
 
      </div> 
 
     ); 
 
     })} 
 
     </div> 
 
    ); 
 
    }; 
 

 
    render() { 
 
    return (
 
     <div className="location"> 
 
     <div className="col-xs-12">{this.renderPositionstatus()}</div> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<StatusBar />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>
이다

+0

내가 가져 오기 명령 내 에서이 일을하고 싶다고 가정하면 동일한 구조를 따르고, renderPositionStatus를 가져 오기로 바꿉니 까? – jpearsonNode

+1

당신은 기술적으로 할 수 있지만 그것에 대한 조언. 필자의 의견으로는 콜백 책임 가져 오기가 ... 음, 데이터를 가져 오는 것입니다. 상태에 반입 된 데이터를 저장합니다. 이번에는 상태가 비어 있지 않은 다른 렌더링 호출을 트리거하고 예를 들어 함수 renderPositionstatus는 새 데이터로 원하는 마크 업을 반환합니다. 'fetch'는 콜백 내에서 데이터를 가져오고 액션을 트리거해야합니다. –

+1

고맙습니다. 그 충고에 감사드립니다. – jpearsonNode

0

JSON 오류 일 수 있지만 개체 내에서 undefined 소품에 액세스하려고합니다.

이것은 당신의 data입니다 :

[ 
    { 
    "key": 0, 
    "Elevation": { 
     "positionValue": "1.11566", 
     "id": 0 
    } 
    }, 
    { 
    "key": 1, 
    "Azimuth": { 
     "positionValue": "1.145657", 
     "id": 1 
    } 
    } 
] 

이 모든 요소 ElevationAzimuth 소품이있다. 첫 번째 것은 Elevation이고 두 번째 것은 Azimuth입니다.

따라서,이 라인은 항상 중단됩니다

let positionStatus = data.map((positioning) => { 
    return (
    <div 
     className="temporary" 
     key={positioning.key} 
    > 
     {positioning.Elevation ? positioning.Elevation.positionValue : 0} : 
     {positioning.Azimuth ? positioning.Azimuth.positionValue : 0} 
    </div> 
) 
}) 

또는

let positionStatus = data.map((positioning) => { 
    return (
    <div 
     className="temporary" 
     key={positioning.key} 
    > 
     {positioning.Elevation 
     ? positioning.Elevation.positionValue 
     : positioning.Azimuth.positionValue 
     } 
    </div> 
) 
}) 
+0

사과, 그리고이를 명확히하기 위해 두 숫자. "/"가 앉아있는 문자열의 부분을 나타 내기위한 것입니다 – jpearsonNode

+0

@jpearsonNode! 그냥 내 대답을 업데이 트했습니다 :) – mersocarlin

관련 문제