基本上,我有一个组件可以调用与IMDB相关的API并将结果发送回去,我可以在控制台中看到结果,但是由于某些原因我无法映射它!
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { searchMovieIMDB } from '../../../actions'
class MovieFormReview extends Component {
componentDidMount() {
this.props.searchMovieIMDB(this.props.formValues.title);
}
fetchMovieResults() {
if(this.props.assets.fetchResultsError) {
return (
<div className="loading">
<h1>{this.props.assets.fetchResultsError}</h1>
</div>
);
} else if(this.props.assets.loadingResults) {
return (
<div className="loading">
<h1>Loading...</h1>
</div>
);
} else {
return this.props.assets.SearchResult.Search.map(series => (
<div className="latest" key={series._id}>
<h1>{series.title}</h1>
</div>
)
)
}
}
render() {
console.log(this.props.assets.SearchResult.Search);
return (
<div className="add-new-asset">
<h2>Please confirm your movie.</h2>
{this.fetchMovieResults()}
</div>
)
}
}
const mapStateToProps = ({ form, assets }) => {
return {
formValues: form.movieForm.values,
assets
}
}
export default connect(mapStateToProps, { searchMovieIMDB })(withRouter(MovieFormReview));
答案 0 :(得分:0)
您的问题很可能是您调用地图时结果为空,但是当您登录到控制台时,已经填充的值。您应该检查值是否被异步填充,如果是,则仅在值被填充时才调用地图。
答案 1 :(得分:0)
请记住,render
将在componentDidMount
之前被调用,因此您的Redux存储在第一次渲染时将为空。在您的fetchMovieResults
中,您的默认行为是遍历this.props.assets.SearchResult.Search
,直到异步调用结束为止,该undefined
将会是this.props.assets.fetchResultsError
。 this.props.assets.loadingResults
和undefined
都将是else
,并以引起错误的else
结尾。
简单的解决方案,请在您的fetchMovieResults() {
if(this.props.assets.fetchResultsError) {
return (
<div className="loading">
<h1>{this.props.assets.fetchResultsError}</h1>
</div>
);
} else if(this.props.assets.loadingResults) {
return (
<div className="loading">
<h1>Loading...</h1>
</div>
);
} else if( typeof this.props.assets.Search !== 'undefined' &&
typeof this.props.assets.SearchResult.Search !== 'undefined') {
return this.props.assets.SearchResult.Search.map(series => (
<div className="latest" key={series._id}>
<h1>{series.title}</h1>
</div>
)
)
}
return null
}
上进行检查:
const arr = [
{ name: 'Bob', age: 12 },
{ name: 'Sam', age: 21 },
{ name: 'Karen', age: 45 }
];
// Without
console.log(JSON.stringify(arr));
// With
console.log(JSON.stringify(arr, null, 2));
答案 2 :(得分:0)
我编写的获取方法具有多种可能的状态,可以在没有错误的每种情况下使用。
此操作的基本思路:您检查所有可能的状态,但如果不匹配,则返回加载状态。
fetchMovieResults() {
const {assets} = this.props;
if (assets) {
if (assets.fetchResultsError) {
// if error
return (
<div className="loading">
<h1>{assets.fetchResultsError}</h1>
</div>
);
} else if (assets.SearchResult && assets.SearchResult.Search && assets.SearchResult.Search.length > 0) {
// if data and more than 0
return assets.SearchResult.Search.map(series => (
<div className="latest" key={series._id}>
<h1>{series.title}</h1>
</div>
));
}
}
// no error or data
// has to be loading
return (
<div className="loading">
<h1>Loading...</h1>
</div>
);
}
为什么我的代码有效但您的代码无效?
(这是猜测,因为我不知道您的所有代码)
componentDidMount
在首次安装并渲染组件后触发,这意味着您的 fetch API 代码在首次渲染组件后触发(这是一种好习惯)。
这意味着您的动作已触发,reduce的第一个渲染器添加了loadingResults
状态 AFTER ,这表示:
if (this.props.assets.fetchResultsError) {
// this check fails
} else if (this.props.assets.loadingResults) {
// this check fails
} else {
// this code runs but you don't have
// data yet and you'll get an error
}
我的回答在每种情况下都有效,因为默认情况下是“加载”状态。