我正在尝试提出一个简单的提取请求,并试图映射响应以显示在页面上。
当我console.log(data)时,API结果正确显示,但是一旦添加映射功能,它们就会显示为未定义。我已经尝试过data.map和data.results.map
我在其他任何线程中都找不到有效的解决方案!
componentDidMount() {
fetch("http://private-cc77e-aff.apiary-mock.com/posts")
.then(results => results.json())
.then(data => {
let posts = data.results.map(post => {
console.log(posts);
});
});
}
任何帮助将不胜感激!
答案 0 :(得分:0)
不确定数据的结构是什么,但是部分问题是您试图在posts
完成填充之前记录.map
。
您可以做的是将从API接收的数据存储在状态下(如果需要对数据进行规范化,请使用map
),然后在渲染中使用this.state.posts
对其进行引用。
别忘了从一个空数组的初始值开始,您可以根据数组的长度有条件地渲染帖子或加载程序。
这是一个小示例,其代码类似于您的用例:
const Joke = ({joke}) => <div style={{border: '1px solid #ccc', padding: '15px'}}>{joke}</div>
class App extends React.Component {
// initial value (array)
state = { jokes: [] }
componentDidMount() {
// get data when component monuted
fetch("https://api.icndb.com/jokes/random/10")
.then(data => data.json())
.then(result => {
// normalize data with map
const jokes = result.value.map(obj => obj.joke);
// update the state for next render
this.setState({jokes})
})
}
render() {
const { jokes } = this.state;
return (
<div>
{
// conditionally render the array or loading (if data isn;t ready yet)
jokes.length
? jokes.map(joke => <Joke joke={joke} />)
: "Loading..."
}
</div>
);
}
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
<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="root" />
答案 1 :(得分:0)
我们不太确定您的API响应如何,但是您在执行日志操作时有点不对。您正在将posts
分配给一个变量,但是您试图在.map
方法中使用它。
我认为您的API响应是这样的:
{
results: [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" },
],
};
这是数据,由于您将data.results
分配为帖子,所以这就是为什么我会这样回答的原因。我正在提供您可以尝试的选项。在这里,我用一个函数模仿了API请求,所以请不要理会这部分。
只需记录整个results
数组。
const data = {
results: [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" },
],
};
const fakeRequest = () =>
new Promise(resolve => setTimeout(() => resolve(data), 1000));
class App extends React.Component {
componentDidMount() {
fakeRequest()
.then( data => {
console.log( data.results );
})
}
render() {
return <div>Look the console. We are logging the whole array.</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>
您可以映射数组并逐项记录每个项目
由于我们只想记录项目,所以我们不需要在这里使用map
,forEach
就足够了。
const data = {
results: [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" },
],
};
const fakeRequest = () =>
new Promise(resolve => setTimeout(() => resolve(data), 1000));
class App extends React.Component {
componentDidMount() {
fakeRequest()
.then( data => {
data.results.forEach( post => console.log( post) )
// or as a shorthand
// data.results.forEach(console.log)
})
}
render() {
return <div>Look the console. We are logging each post one by one.</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>
使用结果设置状态并使用渲染方法将其映射
这是您大多数时候想要做的。据我们所知,仅记录是不够的。
const data = {
results: [
{ id: 1, name: "foo" },
{ id: 2, name: "bar" },
{ id: 3, name: "baz" },
],
};
const fakeRequest = () =>
new Promise(resolve => setTimeout(() => resolve(data), 1000));
class App extends React.Component {
state = {
posts: [],
}
componentDidMount() {
fakeRequest()
.then( data => {
this.setState( { posts: data.results})
})
}
render() {
if ( !this.state.posts.length ) {
return <p>No posts yet</p>
}
return (
<div>
{
this.state.posts.map( post =>
<div key={post.id}>
<p>{post.id}</p>
<p>{post.name}</p>
</div>
)
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>