首页 > 解决方案 > 单击列表中的行星时打开详细页面

问题描述

下面的代码呈现了行星列表(来自此 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

标签: javascriptreactjs

解决方案


添加新功能以获取行星信息。在您的地图中添加 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>
  );
}

推荐阅读