在我的父组件中,我有一个表单,我需要将该表单的输入传递给子组件,我需要它附加到API。我一直试图这样做:
`https://api.icndb.com/jokes/random?=firstName${this.props.name}`
但是我一直收到这个错误:jQuery.Deferred异常:this.state.jokes.map不是函数TypeError:this.state.jokes.map不是函数
当我没有将道具添加到API时,map函数可以正常工作。
完整代码:
家长:
class Input extends Component {
constructor(props){
super(props)
this.state = {
value: ' ',
selected: false
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState(
{value: event.target.value}
);
}
handleSubmit(event) {
this.setState(
{selected: true}
)
}
render() {
return (
<div>
<img src="http://vignette3.wikia.nocookie.net/mugen/images/b/b6/Chuck-norris.png/revision/latest?cb=20120615045306" alt="chuck"/>
<form>
<h1>Whats your name?</h1>
<input type="text" value={this.state.value} onChange={this.handleChange}/>
</form>
<Button onClick={this.handleSubmit} id="submit">
<Link to="/jokes">Submit</Link>
</Button>
{this.state.selected === true
?
<Jokes name={this.state.value} />
:
null
}
</div>
)
}
}
孩子:
class Jokes extends Component {
constructor(props){
super(props);
this.state = {jokes: []}
this.JokeList = this.JokeList.bind(this)
}
componentDidMount() {
this.JokeList()
}
JokeList() {
return $.getJSON(`https://api.icndb.com/jokes`)
.then((data) =>{
this.setState({ jokes: data.value })
console.log(this.state.jokes)
});
}
render(){
const funnies = this.state.jokes.map((item, i) => {
return <div id="quoteList">
<h1 id="num" className="answers" key="id">{item.id}</h1>
<h2 id="quote" className="answers" key="yoke">{item.joke}</h2>
</div>
})
return(
<div> { funnies } </div>
)
}
}
非常感谢任何帮助!!
答案 0 :(得分:0)
我已经检查了发生了什么。
当您请求https://api.icndb.com/jokes/random?=firstName${this.props.name}
时,由于过滤标准,它很可能只返回一条记录。
在这种情况下,API会返回一个Object,而不是一个带有一个元素的数组。这就是你得到错误的原因:
this.state.jokes.map不是函数
但是,我调整了您的代码以支持这两种情况,请查看下面的示例。一旦我们得到回复,这就是我所做的:
// Make sure the jokes are an Array, because of we iterate over them later.
let jokes = Array.isArray(data.value) ? data.value : [data.value];
this.setState({ jokes });
class Input extends React.Component {
constructor(props){
super(props)
this.state = {
value: ' ',
selected: false
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState(
{value: event.target.value}
);
}
handleSubmit(event) {
this.setState(
{selected: true}
)
}
render() {
return (
<div>
<img src="http://vignette3.wikia.nocookie.net/mugen/images/b/b6/Chuck-norris.png/revision/latest?cb=20120615045306" alt="chuck"/>
<form>
<h1>Whats your name?</h1>
<input type="text" value={this.state.value} onChange={this.handleChange}/>
</form>
<input type="button" value="Submit" onClick={this.handleSubmit} id="submit" />
{this.state.selected === true
?
<Jokes name={this.state.value} />
:
null
}
</div>
)
}
}
class Jokes extends React.Component {
constructor(props){
super(props);
this.state = {jokes: []}
this.JokeList = this.JokeList.bind(this)
}
componentDidMount() {
this.JokeList()
}
JokeList() {
return $.getJSON(`https://api.icndb.com/jokes/random?=firstName${this.props.name}`)
.then((data) =>{
// Make sure the jokes are an Array, because of we iterate over them later.
let jokes = Array.isArray(data.value) ? data.value : [data.value];
this.setState({ jokes });
});
}
render(){
const funnies = this.state.jokes.map((item, i) => {
return <div id="quoteList">
<h1 id="num" className="answers" key="id">{item.id}</h1>
<h2 id="quote" className="answers" key="yoke">{item.joke}</h2>
</div>
})
return(
<div> { funnies } </div>
)
}
}
ReactDOM.render(<Input />, document.getElementById('container'));
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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="container"></div>
&#13;