[英]How do I only render one result in a separate component using axios in React?
Edit// 编辑//
I suppose my question isn't so clear. 我想我的问题不是那么清楚。 I'm trying to get one park returned when my url points to http://localhost:1233/details/ '${parkcode}'. 当我的网址指向http:// localhost:1233 / details / '$ {parkcode}'时,我正试图让一个公园返回。 I've defined the param for the url in my results.js file. 我在results.js文件中为url定义了param。 But I'm having trouble in defining the this.setState in my details.js to render just one result of the park based on the id which also happens to be the park code. 但是我在我的details.js中定义this.setState时遇到麻烦,只根据id来渲染park的一个结果,这也恰好是park代码。
I'm new to React (and possibly to JavaScript, I don't know anymore). 我是React的新手(也可能是JavaScript,我不知道了)。 I am following a tutorial - instead of using an npm package for an API I decided to branch out and use axios.get() to fetch data from an API. 我正在学习一个教程 - 而不是使用npm包作为API我决定分支出来并使用axios.get()从API获取数据。 I am able to render the results from a component into the browser, however after adding on reach-router (I assume it's similar to React Router), I am having troubles rendering just one result of my API call as the page I am attempting to build is supposed to only show ONE result based on the ID I have defined. 我能够将组件的结果渲染到浏览器中,但是在添加到达路由器之后(我假设它与React路由器类似),我只能将我的API调用的一个结果渲染为我尝试的页面build应该只根据我定义的ID显示一个结果。
In my main file, which is Results.js here, I am able to get the data with no problem and include them in my file using JSX and render them. 在我的主文件(这里是Results.js)中,我能够毫无问题地获取数据,并使用JSX将它们包含在我的文件中并渲染它们。 I'm attempting to use the same logic as I did in that page in my Details.js page (which is the page that is supposed to show only one result to the ID in the route). 我试图在我的Details.js页面中使用与我在该页面中所做的逻辑相同的逻辑(该页面应该只向路径中的ID显示一个结果)。
How I'm using axios in Results.js 我如何在Results.js中使用axios
componentDidMount() {
axios
.get(
"https://developer.nps.gov/api/v1/parks?stateCode=wa&fields=images&api_key=" +
`${nps}`
)
// https://css-tricks.com/using-data-in-react-with-the-fetch-api-and-axios/
.then(res =>
res.data.data.map(park => ({
description: `${park.description}`,
fullname: `${park.fullName}`,
states: `${park.states}`,
parkcode: `${park.parkCode}`,
image: `${park.images[0] ? park.images[0].url : "No Image"}`,
designation: `${park.designation}`
}))
)
.then(parks => {
this.setState({
parks
});
console.log(parks);
});
}
How I'm attempting to use the same logic in Details.js 我是如何尝试在Details.js中使用相同的逻辑
It's not recognizing park.name even though I did the API call. 即使我进行了API调用,它也无法识别park.name。 However, if I hard code park[0].name it works. 但是,如果我硬编码park [0] .name它可以工作。 I have no idea what I'm doing wrong here. 我不知道我在这里做错了什么。 It might be an obvious problem but help me. 这可能是一个明显的问题,但帮助我。
class Details extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
}
}
componentDidMount() {
axios
.get(
"https://developer.nps.gov/api/v1/parks?stateCode=wa&fields=images&api_key=" +
`${nps}`,
{ id: this.props.id }
).then(res => {
const park = res.data.data.map(park => ({
description: `${park.description}`,
fullname: `${park.fullName}`,
states: `${park.states}`,
parkcode: `${park.parkCode}`,
image: `${park.images[0] ? park.images[0].url : "No Image"}`,
designation: `${park.designation}`
}))
console.log(park.name);
this.setState({
name: park.name;
loading: false
})
}).catch(err => {
this.setState({error: err});
})
}
I'm expecting the page to recognize the id as defined in the GET request along with the axios, and render the park details in relation to the id. 我希望页面能够识别GET请求中定义的id以及axios,并渲染与id相关的公园详细信息。 But now, it's doing none of it and I've been stuck on this for forever :( 但现在,它没有做到这一点,我一直坚持这个永远:(
I believe this is the part you are getting wrong 我相信这是你错了
const parks = res.data.data.map(park => ({
description: `${park.description}`,
fullname: `${park.fullName}`,
states: `${park.states}`,
parkcode: `${park.parkCode}`,
image: `${park.images[0] ? park.images[0].url : "No Image"}`,
designation: `${park.designation}`
}))
console.log(parks) // this should display your array of all parks
this.setState({
parks,
loading: false
})
displayParks(parks) {
const allParks = parks.map((park, index) => {
return <div key={park.parkCode}>{park.fullname}<div>
})
}
render() {
const { parks } = this.state;
const displayParks = parks && parks.length > 0 ? this.displayParks(parks) : <div>Loading parks</div>
return (
<div>{ displayParks }</div>
);
}
When you do a .map on an array you are basically creating another array and that is what is returned to your park
variable. 当您在数组上执行.map时,您基本上创建了另一个数组,这是返回到park
变量的内容。
So in your render method, you can then loop over every item in parks
因此,在渲染方法中,您可以遍历parks
每个项目
You can try this in .then()
你可以在.then()
试试这个
let park = res.data.data.map(park => ({
description: `${park.description}`,
fullname: `${park.fullName}`,
states: `${park.states}`,
parkcode: `${park.parkCode}`,
image: `${park.images[0] ? park.images[0].url : "No Image"}`,
designation: `${park.designation}`
}))
park = park[0]; // convert arrays of parks to single park
console.log(park.fullname); // now you can use `park.fullname`
or this 或这个
const park = {
description: `${res.data.data[0].description}`,
fullname: `${res.data.data[0].fullName}`,
states: `${res.data.data[0].states}`,
parkcode: `${res.data.data[0].parkCode}`,
image: `${res.data.data[0].images[0] ? park.images[0].url : "No Image"}`,
designation: `${res.data.data[0].designation}`
}
console.log(park.fullname); // now you can use `park.fullname`
otherwise do it in API 否则在API中执行
I think you can first set a state for your responses and then try to show them 我认为您可以先为您的回复设置状态,然后尝试显示它们
same this : 同样的:
state = {
result: []
}
componentDidMount() {
axios
.get("https://developer.nps.gov/api/v1/parks?stateCode=wa&fields=images&api_key=" +`${nps}`).then((res) => {
this.setState({result: res.data.data})
})
}
render(){
const result = this.state.result.map((el, index) => {
return(
//data
)
})
return(
<div>
{result}
</div>
)
}
There are some unnecessary parts in your code. 您的代码中有一些不必要的部分。 You don't need to construct your data as you do in your setState
part. 您不需要像在setState
部分中那样构建数据。 You are getting park list and it is already a structured data. 您正在获取停车清单,它已经是结构化数据。 So, just set your state with the data you get back. 因此,只需使用您获得的数据设置您的状态即可。
After that, you can map over this data and render the parks with links for React Router. 之后,您可以映射此数据并使用React Router的链接渲染公园。 You can use parkCode
as your URL param for Link
. 您可以使用parkCode
作为Link
的URL参数。 In Details
component you can extract this parkCode
and make a new request for park details, then set this to your state. 在“ Details
组件中,您可以提取此parkCode
并对停车详细信息发出新请求,然后将其设置为您的状态。
I'm providing an example. 我提供了一个例子。
index.js index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Results from "./Results";
import Details from "./Details";
const Routes = () => (
<Router>
<Switch>
<Route exact path="/" component={Results} />
<Route path="/details/:parkCode" component={Details} />
</Switch>
</Router>
);
ReactDOM.render(<Routes />, document.getElementById("root"));
Results 结果
import React from "react";
import axios from "axios";
import { Link } from "react-router-dom";
class Results extends React.Component {
state = {
parks: [],
loading: true,
};
componentDidMount() {
axios(
"https://developer.nps.gov/api/v1/parks?stateCode=wa&fields=images&api_key=LbqZVj21QMimfJyAHbPAWabFaBmfaTZtseq5Yc6t"
).then(res => this.setState({ parks: res.data.data, loading: false }));
}
renderParks = () =>
this.state.parks.map(park => (
<Link to={`/details/${park.parkCode}`} key={park.parkCode}>
<div>{park.fullName}</div>
</Link>
));
render() {
return (
<div>{this.state.loading ? <p>Loading...</p> : this.renderParks()}</div>
);
}
}
export default Results;
Details 细节
import React from "react";
import axios from "axios";
class Details extends React.Component {
state = { park: "", loading: true };
componentDidMount() {
const { match } = this.props;
axios(
`https://developer.nps.gov/api/v1/parks?parkCode=${match.params.parkCode}&api_key=${nps}`
).then(res => this.setState({ park: res.data.data[0], loading: false }));
}
render() {
return (
<div>
{this.state.loading ? <p>Loading...</p> : this.state.park.description}
</div>
);
}
}
export default Details;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.