嗨我有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>
);
}
}
答案 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()
。