reactjs map函数中的json解析错误不起作用

时间:2018-04-03 19:47:46

标签: reactjs

嗨我有json对象如下:

{
  "id":1,"name":"Save the Queen - Corporate Carrom Tournament - 2018", "date":"28 may 2018","address":"Active Arena, Opposite Prestige Tech Park (Behind Croma) Outer Ring Road, Marathahalli, Kadubeesanahalli, Panathur,, Bengaluru, Karnataka 560103","banner":"https://preview.ibb.co/fTSnKn/badminton_blr.jpg", 


  "sports":[
      {"name":"Badminton","categoreis":[
        {"name":"Men Singles","fee":"600","gst":"108","formid":102,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"}]
        },
        {"name":"Men Doubles","fee":"1200","gst":"216","formid":103,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"},
        {"label":"Partner Name:","paramname":"partner_name","type":"text"},
        {"label":"Partner Email:","paramname":"partner_email","type":"text"}]
        },
        {"name":"Women Doubles","fee":"1200","gst":"216","formid":104,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"},
        {"label":"Partner Name:","paramname":"partner_name","type":"text"},
        {"label":"Partner Email:","paramname":"partner_email","type":"text"}]
        }
    ]
},

{"name":"Carrom","categoreis":[
        {"name":"Men Singles","fee":"399","gst":"72","formid":105,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"}]
        },
        {"name":"Men Doubles","fee":"799","gst":"144","formid":106,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"},
        {"label":"Partner Name:","paramname":"partner_name","type":"text"},
        {"label":"Partner Email:","paramname":"partner_email","type":"text"}]
        },
        {"name":"Women Doubles","fee":"799","gst":"144","formid":107,"form":[{"label":"Name:","paramname":"name","type":"text"},
        {"label":"Email:","paramname":"email","type":"text"},
        {"label":"Phone:","paramname":"phone","type":"text"},
        {"label":"Partner Name:","paramname":"partner_name","type":"text"},
        {"label":"Partner Email:","paramname":"partner_email","type":"text"}]
        }
    ]
}

]}

但是当我在渲染函数中解析它时,我会得到"无法读取属性' map'未定义"。有人可以帮助我在哪里犯错误吗?

this.state.tournament_detail.sports.map(
      function(sport,index){
        if(index==1){
          list1.push(<li class="active"><a data-toggle="tab" href={"#"+index}>{sport.name}</a></li>);
        }else{
          list1.push(<li><a data-toggle="tab" href={"#"+index}>{sport.name}</a></li>);
        }
      }
    )

我已正确验证this.state.tournament_detail已正确设置为上面给出的json。

完整的源代码是这个

import React,{Component} from 'react';
import style1 from './../css/main.css';
import RegisterWindow from './RegisterWindow.js';
import Modal from 'react-modal';
import axios from 'axios';

var styles={
  container:{
  boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)",
  textAlign: "center",
  margin:"auto",
  marginTop:"10px",
  borderRadius:"0.5vw",
  padding:"20px"
  },
  content : {
    top                   : '50%',
    left                  : '50%',
    right                 : 'auto',
    bottom                : 'auto',
    marginRight           : '-50%',
    transform             : 'translate(-50%, -50%)'
  }
}
Modal.setAppElement('#app')

export default class TournamentDetail extends Component{

  constructor(props){
    super(props);
    this.state = {
     modalIsOpen: false,
     no_of_tickets:0,
     net_amount:0,
     tournament_detail:{}
   };

   this.openModal = this.openModal.bind(this);
   this.afterOpenModal = this.afterOpenModal.bind(this);
   this.closeModal = this.closeModal.bind(this);
   this.test=this.test.bind(this);
  }

  componentWillMount(){
  //  alert('1');
    var self=this;
    axios.get('http://localhost:3000/get-tournament-detail')
      .then(function (response) {
        console.log(response.data);
        self.setState({tournament_detail:response.data});
      }).catch(function (error) {
        console.log(error);
      });
  }

  openModal() {
   this.setState({modalIsOpen: true});
 }

 afterOpenModal() {
   // references are now sync'd and can be accessed.
   //this.subtitle.style.color = '#f00';
 }

 closeModal() {
   this.setState({modalIsOpen: false});
 }

test(event,data){
  event.preventDefault();
  alert(data);
  alert(event.target.value);
  alert('1');
  this.setState({modalIsOpen: false});
}

  render(){
    var self=this;

    var list1=[];
    var list2=[];
    JSON.parse(this.state.tournament_detail).sports.map(
      function(sport,index){
        if(index==1){
          list1.push(<li class="active"><a data-toggle="tab" href={"#"+index}>{sport.name}</a></li>);
        }else{
          list1.push(<li><a data-toggle="tab" href={"#"+index}>{sport.name}</a></li>);
        }
      }
    )

    return (
      <div class="container" style={styles.container}>

      <Modal isOpen={this.state.modalIsOpen} onAfterOpen={this.afterOpenModal} onRequestClose={this.closeModal} contentLabel="Example Modal">
          <RegisterWindow close={this.test}/>
      </Modal>

        <div class="row" style={{borderBottomStyle:"ridge",borderBottomColor:"#0082c8",marginBottom:"10px",paddingBottom:"10px"}}>
          <div class="col-sm-8"><img style={{width:"100%",height:"100%"}} src={this.state.tournament_detail.banner}/></div>
          <div class="col-sm-4">
            <div class="row">
              <div class="col" style={{borderBottomStyle:"solid",borderWidth: ".5px"}}>
                  <p style={{textAlign:"left"}}>{this.state.tournament_detail.name}</p>
              </div>
            </div>
            <div class="row" style={{marginTop:"10px"}}>
              <div class="col" style={{textAlign:"left"}}><i class="fa fa-calendar"></i>  {this.state.tournament_detail.date}</div>
            </div>
            <div class="row" style={{marginTop:"10px"}}>
              <div class="col" style={{textAlign:"left"}}><i class="fa fa-map-marker"></i>    {this.state.tournament_detail.address}</div>
            </div>
            <div class="row" style={{marginTop:"20px"}}>
              <div class="col"><a href="#" style={{backgroundColor:"#ffc800",padding:"10px",borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}} onClick={this.openModal} >Register</a> </div>
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <p style={{fontSize:"18px",float:"left",fontWeight:"500"}}>Pricing and Offers</p>
          </div>
        </div>
        <div  style={{borderStyle:"dotted",borderWidth: ".5px"}}>

        <ul class="nav nav-tabs">
          <li class="active"><a data-toggle="tab" href="#badminton">Badminton</a></li>
          <li><a data-toggle="tab" href="#tt">Table Tennis</a></li>
          <li><a data-toggle="tab" href="#carrom">Carrom</a></li>
        </ul>

        <div class="tab-content">
           <div id="badminton" class="tab-pane fade in active">

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}} onClick={this.openModal}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>
               </div>
           </div>


           </div>
           <div id="tt" class="tab-pane fade">

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 499 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>
               </div>
           </div>

           </div>
           <div id="carrom" class="tab-pane fade">

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>

               </div>
           </div>
           <div style={{borderBottomStyle:"solid",borderWidth: "thin"}}></div>

           <div className={style1.elem}>
               <div class="row"  style={{padding:"20px"}}>
                 <div class="col-sm-8">
                   <p style={{textAlign:"left"}}> Mens Singles</p>
                   <p style={{display:"block",textAlign:"left"}}> 399 +GST 72</p>
                 </div>
                 <div class="col-sm-4"><p style={{float:"left"}}>471/-</p>
                   <a href="#" style={{backgroundColor:"#ffc800",padding:"10px", borderRadius:"0.5vw",color:"#707070",textDecoration:"none"}}>Register</a>
                 </div>
               </div>
           </div>

           </div>
         </div>

        </div>

        <div class="row">
          <div class="col">
            <p style={{fontSize:"18px",float:"left",fontWeight:"500"}}>Detail</p>
          </div>
        </div>
        <div  style={{borderStyle:"dotted",borderWidth: ".5px"}}>
          <div style={{textAlign:"justify"}} dangerouslySetInnerHTML={{__html: this.state.tournament_detail.detail}} />
        </div>
      </div>
    );
  }

}

2 个答案:

答案 0 :(得分:1)

我认为问题与您所拥有的异步流有关。

// can be componentWillMount
componentDidMount(){
  // fetch
  fetchMyDataFromServer()
    // initial state equal to {}
    .then(data => this.setState({tournament_detail: data}))
}
...
render(){
  // check if your state is not empty
  const { tournament_detail } = this.state
  return (
     <div>
       {Object.keys(tournament_detail).length > 0
         ? //... do what you want
         : // otherwise display a loading...
       }
     </div>
  )
}

此外Array.propotype.map方法返回一个新数组,因此不需要在其中使用push。只需将push替换为return语句:)

Here是一个很好解释的答案,使用与您类似的流程

希望它有意义。

答案 1 :(得分:0)

试试JSON.parse(this.state.tournament_detail).sports.map()

如果有效,请执行JSON.parse所在的setting state.tournament_detail,这样您就不必在每次渲染时都这样做。然后你可以直接this.state.tournament_detail.sports.map()