javascript - 单击列表中的行星时打开详细页面
问题描述
下面的代码呈现了行星列表(来自此 API:https : //swapi.dev/)。我正在尝试找到一种方法让我的行星可点击。当在列表中单击特定行星时,它应该打开一个详细页面,其中包含已单击行星的特定信息(从 API 中提取)。我可以用 or 做到这一点吗?执行此操作的最佳实践方法是什么?
import React, { PureComponent } from 'react'
import axios from "axios";
class Home extends PureComponent {
constructor(props) {
super(props)
this.state = {
planets: [],
filteredPlanets: []
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(e){ // eslint-disable-next-line
let planetssearchlist = this.state.planets.filter(planet => {
if(planet.name){
if(planet.name.toLowerCase().includes(e.target.value.toLowerCase())){
return true
}
}
})
this.setState({
filteredPlanets: planetssearchlist
})
}
componentDidMount(){
axios({
method: "GET",
url: "https://swapi.dev/api/planets/"
})
.then(response => {
console.log(response)
let planetslist = response.data.results;
this.setState({planets: planetslist, filteredPlanets: planetslist})
})
.catch(error => {
console.log("You've made an error with the planets load charles: ",error)
})
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input placeholder="searchbar" type="text" onChange={this.handleChange}></input>
</form>
{
this.state.filteredPlanets.map((planet,i) => (
<p key={i}>{planet.name}</p>
))
}
</div>
)
}
}
export default Home
解决方案
添加新功能以获取行星信息。在您的地图中添加 onClick 事件处理程序以获取单击行星的行星信息。
向您的状态添加两个新变量
this.state = {
planets: [],
filteredPlanets: [],
planetInfo: {},
isGettingPlanetInfo: false,
};
添加获取行星信息的函数
getPlanetInfo = url => {
this.setState({
isGettingPlanetInfo: true
})
axios({
method: "GET",
url: url
})
.then(response => {
console.log(response.data)
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false,
})
})
.catch(error => {
this.setState({
isGettingPlanetInfo: false
})
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
将点击事件处理程序添加到星球
{this.state.filteredPlanets.map((planet, i) => (
<p onClick={() => this.getPlanetInfo(planet.url)} key={i}>
{planet.name}
</p>
))}
主页组件
import React, { PureComponent } from 'react';
import axios from 'axios';
export default class Home extends PureComponent {
constructor(props) {
super(props);
this.state = {
planets: [],
filteredPlanets: [],
planetInfo: {},
isGettingPlanetInfo: false,
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
// eslint-disable-next-line
let planetssearchlist = this.state.planets.filter((planet) => {
if (planet.name) {
if (planet.name.toLowerCase().includes(e.target.value.toLowerCase())) {
return true;
}
}
});
this.setState({
filteredPlanets: planetssearchlist,
});
}
getPlanetInfo = (url) => {
this.setState({
isGettingPlanetInfo: true,
});
axios({
method: 'GET',
url: url,
})
.then((response) => {
console.log(response.data);
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false,
});
})
.catch((error) => {
this.setState({
isGettingPlanetInfo: false,
});
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
componentDidMount() {
axios({
method: 'GET',
url: 'https://swapi.dev/api/planets/',
})
.then((response) => {
console.log(response);
let planetslist = response.data.results;
this.setState({ planets: planetslist, filteredPlanets: planetslist });
})
.catch((error) => {
console.log(
"You've made an error with the planets load charles: ",
error
);
});
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input
placeholder='searchbar'
type='text'
onChange={this.handleChange}
/>
</form>
{this.state.filteredPlanets.map((planet, i) => (
<p onClick={() => this.getPlanetInfo(planet.url)} key={i}>
{planet.name}
</p>
))}
<hr />
{this.state.isGettingPlanetInfo ? (
<p>getting planet info...</p>
) : typeof this.state.planetInfo === 'object' &&
Object.keys(this.state.planetInfo).length ? (
<div>
<p>name: {this.state.planetInfo.name}</p>
<p>climate: {this.state.planetInfo.climate}</p>
<p>population: {this.state.planetInfo.population}</p>
</div>
) : (
''
)}
</div>
);
}
}
使用反应路由器
import React, { PureComponent } from "react";
import axios from "axios";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
class PlanetInfo extends React.Component {
state = {
url: "",
planetInfo: {},
isGettingPlanetInfo: false
};
getPlanetInfo = () => {
this.setState({
isGettingPlanetInfo: true
});
axios({
method: "GET",
url: this.state.url
})
.then(response => {
console.log(response.data);
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false
});
})
.catch(error => {
this.setState({
isGettingPlanetInfo: false
});
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
componentDidMount = () => {
this.setState(
{
url: this.props.location.state.planet.url
},
this.getPlanetInfo
);
};
render() {
return (
<div>
{this.state.isGettingPlanetInfo ? (
<p>getting planet info...</p>
) : typeof this.state.planetInfo === "object" &&
Object.keys(this.state.planetInfo).length ? (
<div>
<p>name: {this.state.planetInfo.name}</p>
<p>climate: {this.state.planetInfo.climate}</p>
<p>population: {this.state.planetInfo.population}</p>
</div>
) : (
""
)}
</div>
);
}
}
class Home extends PureComponent {
constructor(props) {
super(props);
this.state = {
planets: [],
filteredPlanets: []
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
// eslint-disable-next-line
let planetssearchlist = this.state.planets.filter(planet => {
if (planet.name) {
if (planet.name.toLowerCase().includes(e.target.value.toLowerCase())) {
return true;
}
}
});
this.setState({
filteredPlanets: planetssearchlist
});
}
componentDidMount() {
axios({
method: "GET",
url: "https://swapi.dev/api/planets/"
})
.then(response => {
console.log(response);
let planetslist = response.data.results;
this.setState({ planets: planetslist, filteredPlanets: planetslist });
})
.catch(error => {
console.log(
"You've made an error with the planets load charles: ",
error
);
});
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input
placeholder="searchbar"
type="text"
onChange={this.handleChange}
/>
</form>
{this.state.filteredPlanets.map((planet, i) => (
<Link to={{ pathname: "/info", state: { planet: planet } }}>
<p key={i}>{planet.name}</p>
</Link>
))}
</div>
);
}
}
export default function Navigation() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/info" component={PlanetInfo} />
</Switch>
</BrowserRouter>
);
}
推荐阅读
- reactjs - 如何在重新渲染时更新 API 调用?
- windows - 如何在wsl(windows子系统linux)中为shell添加右键单击上下文菜单?
- java - 使用流从元组列表中生成列表元组
- javascript - 语句之间如何使用逗号运算符?
- python - 计算结转效应
- string - 如何将数字与小数点匹配
- c# - 如何从 Azure Service Fabric 无状态服务访问 appsettings.json
- laravel - 成功部署 Azure devops 后 Azure Web App wwwroot 未更新
- python - 如何批量插入或创建多个数据
- reactjs - react中的嵌套路由不渲染嵌套组件