我有一个组件,该组件使用axios来访问PubMed api(位于componentDidMount中),检索一些发布ID,然后将其存储为“ idlist”状态。然后调用第二个函数(addPapers),该函数传入此ID列表,并进行第二次api调用,以检索每个ID的更多详细信息(标题,期刊,作者)。所有这些似乎都可以正常工作,当我使用React工具检查状态时,有一个数组(“ paperList”)充满了具有预期key:value对的对象。但是,当我尝试映射此数组并访问render函数中的对象(即paper.title,paper.author,paper.journal)中的值时,它们将返回未定义状态。我使用反应时间不长,怀疑我犯了一个基本错误,但无法弄清楚。
我已经尝试过console.logging每个步骤,并且预期的数据处于状态并且在React工具中是正确的
import axios from 'axios'
import './App.css';
import rateLimit from 'axios-rate-limit';
class App extends Component {
state= {
idlist: [],
papersList : ""
}
componentDidMount () {
console.log("incomponent")
axios.get("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&retmode=json&retmax=1000&term=((Australia%5Bad%5D)%20AND%20(%222019%2F07%2F01%22%5BDate%20-%20Publication%5D%20%3A%20%223000%22%5BDate%20-%20Publication%5D))%20AND%20(%22nature%22%5BJournal%5D%20OR%20%22Nature%20cell%20biology%22%5BJournal%5D%20OR%20%22Nature%20structural%20%26%20molecular%20biology%22%5BJournal%5D)")
.then (response =>
this.setState({idlist: response.data.esearchresult.idlist}, () => {
this.addPapers(this.state.idlist)
}
)
)}
addPapers = (idlist) => {
if (idlist) {
const http = rateLimit(axios.create(), { maxRequests: 6, perMilliseconds: 1000 })
const list = this.state.idlist.map(id => {
let paperObj ={};
let paperList =[]
http.get(`https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json&rettype=abstract&id=${id}&api_key=9476810b14695bd14f228e63433facbf9c08`)
.then (response2 => {
const title = response2.data.result[id].title
const journal = response2.data.result[id].fulljournalname
const authorList = []
const authors = response2.data.result[id].authors
authors.map((author, idx) =>
idx > 0 ? authorList.push(" " + author.name) : authorList.push(author.name))
paperObj.title = title
paperObj.journal = journal
paperObj.authors = authorList.toString()
paperList.push(paperObj)
})
return paperObj
})
this.setState({papersList: list})
}
}
render () {
let article = ""
if (this.state.papersList.length){
article = this.state.papersList.map(paper =>
console.log (paper.title)
console.log (paper.authors)
console.log (paper.journal)
)
}
return (
<div className="App">
<h1>Publications</h1>
{article}
</div>
);
}
}
export default App;
我希望当我映射到paperList并提取每篇论文时,我应该能够使用console.log(paper.title),console.log(paper.title),console.log( paper.title)。这些都返回未定义。
答案 0 :(得分:2)
您在代码中遇到两个问题
1)paperList
数组声明应该在映射循环之外。
2)应该返回paperList
而不是paperObj
下面的工作代码对render
功能进行了一些增强
import React from "react";
import ReactDOM from "react-dom";
import rateLimit from "axios-rate-limit";
import axios from "axios";
import "./styles.css";
class App extends React.Component {
state = {
idlist: [],
papersList: ""
};
componentDidMount() {
console.log("incomponent");
axios
.get(
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&retmode=json&retmax=1000&term=((Australia%5Bad%5D)%20AND%20(%222019%2F07%2F01%22%5BDate%20-%20Publication%5D%20%3A%20%223000%22%5BDate%20-%20Publication%5D))%20AND%20(%22nature%22%5BJournal%5D%20OR%20%22Nature%20cell%20biology%22%5BJournal%5D%20OR%20%22Nature%20structural%20%26%20molecular%20biology%22%5BJournal%5D)"
)
.then(response =>
this.setState({ idlist: response.data.esearchresult.idlist }, () => {
this.addPapers(this.state.idlist);
})
);
}
addPapers = idlist => {
if (idlist) {
const http = rateLimit(axios.create(), {
maxRequests: 6,
perMilliseconds: 1000
});
let paperList = [];
this.state.idlist.forEach(id => {
let paperObj = {};
http
.get(
`https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json&rettype=abstract&id=${id}&api_key=9476810b14695bd14f228e63433facbf9c08`
)
.then(response2 => {
const title = response2.data.result[id].title;
const journal = response2.data.result[id].fulljournalname;
const authorList = [];
const authors = response2.data.result[id].authors;
authors.map((author, idx) =>
idx > 0
? authorList.push(" " + author.name)
: authorList.push(author.name)
);
paperObj.title = title;
paperObj.journal = journal;
paperObj.authors = authorList.toString();
paperList.push(paperObj);
})
.then(result => {
this.setState({ papersList: paperList });
});
});
}
};
render() {
return (
<div className="App">
<h1>Publications</h1>
{this.state.papersList.length &&
this.state.papersList.map(data => {
return <div>{data.title}</div>;
})}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
希望有帮助!
答案 1 :(得分:0)
这样做:
render () {
let article;
if (this.state.papersList.length){
article = this.state.papersList.map(paper => <p>span>Title is {paper.title}</span></p> )
}
return (
<div className="App">
<h1>Publications</h1>
{article}
</div>
);
}