无需单击按钮即可调用组件获取

时间:2020-09-13 11:41:01

标签: html reactjs components

我想使用pokeApi制作一个有关pokemons的程序,该程序具有一个带有2个按钮的导航栏:PokemonList和TypeList。

这是我的App.js:

import React from "react";
import "./App.css";
import NavBar from "./components/Navbar";
import PokemonList from "./components/PokemonList";

class App extends React.Component {
  state = {
    pokemons: undefined,
  };

  getPokemons = async (e) => {
    e.preventDefault();
    const api_call = await fetch("https://pokeapi.co/api/v2/pokemon");
    const data = await api_call.json();
    console.log("Data logging should come here!");
    console.log(data);
    this.setState({
      pokemons: data.results,
    });
  };
  render() {
    return (
      <div>
        <NavBar getPokemons={this.getPokemons} />
        <PokemonList pokemons={this.state.pokemons} />
      </div>
    );
  }
}

export default App;

这是我的NavBar.js:

import React from "react";
import "bootstrap/dist/css/bootstrap.css";
import {
  Collapse,
  Navbar,
  NavbarToggler,
  NavbarBrand,
  Nav,
  NavItem,
  NavLink,
  UncontrolledDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
  NavbarText,
  NavDropdown,
  Form,
  FormControl,
  Button,
} from "react-bootstrap";

const NavBar = (props) => (
  <Navbar bg="bg" expand="lg">
    <Navbar.Toggle aria-controls="basic-navbar-nav" />
    <Navbar.Collapse id="basic-navbar-nav">
      <Nav className="mr-auto">
        <Nav.Link onClick={props.getPokemons}>Pokemons</Nav.Link>
        <Nav.Link href="#link">Types</Nav.Link>
      </Nav>
    </Navbar.Collapse>
  </Navbar>
);

export default NavBar;

这是我的PokemonList.js

import React from "react";

class PokemonList extends React.Component {
  getKeys = function () {
    console.log(this.props);
    return Object.keys(this.props.data[0]);
  };

  getHeader = function () {
    let keys = this.getKeys();
    return keys.map((key, index) => {
      return <th key={key}>{key.toUpperCase()}</th>;
    });
  };

  getRowsData = function () {};

  render() {
    const RenderRow = (props) => {
      let items = this.props.data;
      let keys = this.getKeys();
      return items.map((row, index) => {
        return (
          <tr key={index}>
            <RenderRow key={index} data={row} keys={keys} />
          </tr>
        );
      });
    };
    return (
      <div>
        <table>
          <thead>
            <tr>{this.getHeader()}</tr>
          </thead>
          <tbody>{this.getRowsData()}</tbody>
        </table>
      </div>
    );
  }
}

export default PokemonList;

我的问题是我使用npm start启动了应用程序,但出现错误:

TypeError:无法读取未定义的属性“ 0” 在PokemonList.js-> getKeys()函数中。

我不明白,因为仅当我单击PokemonList按钮时才应调用fetch,但在开始时会调用它。任何想法?另外一个是我的NavBar.js丑陋,因为要导入,是否还有其他方法可以在一行中导入这些东西?

2 个答案:

答案 0 :(得分:1)

您正在使用异步函数获取pokemons数据,所以发生的事情是当仍需要返回pokemons数据时呈现了组件。

为了修复它,请尝试用条件包装您的PokemonList组件;这样,我们仅在检索到宠物小精灵数据时才显示PokemonList组件:

{this.state.pokemons && <PokemonList pokemons={this.state.pokemons} />}

要注意我使用了'&&'运算符,这是if语句的快捷方式-在javascript中,它计算第一个表达式,如果返回0或“”或false或undefined或null,则它不求值“ &&”运算符之后的表达式。

这种罪过的替代品是这样的:

{this.state.pokemons ? <PokemonList pokemons={this.state.pokemons} /> : null}

答案 1 :(得分:0)

您没有将任何道具传递给<PokemonList pokemons={this.state.pokemons} />组件。

您应该在App.js中这样做:

import PokemonList from "./components/PokemonList";
...
...
<PokemonList pokemons={this.state.pokemons} data={this.state.data} />
...
...
相关问题