反应-单击对象时按对象属性过滤道具

时间:2018-12-04 12:38:13

标签: reactjs

我有我的主要组件,我在其中获取github存储库api,将其置于组件的状态,然后将数据通过props传递给另一个组件(“ SecondComponent”)。

“ SecondComponent”呈现按钮列表,这应该允许我按语言过滤回购道具(显示回购的语言等于按钮的ID)。该组件还应该呈现过滤后的回购列表(另一个组件)。

enter image description here

屏幕肯定比我更能解释问题。

我应该在哪个组件中应用过滤道具的功能?

代码如下:

import React, { Component } from "react";
import "./App.css";
const REPOURL =
  "https://api.github.com/search/repositories?q=stars:%3E1&sort=stars&order=desc&type=Repositories";

class App extends Component {
  constructor() {
    super();
    this.state = {
      reps: [],
      langs: ["All", "JavaScript", "Ruby", "Java", "CSS", "Python"]
    };
  }

  componentDidMount() {
    fetch(REPOURL)
      .then(result => result.json())
      .then(data => this.setState({ reps: data.items }));
  }

  render() {
    return (
      <main>
        <h1>Repositiories</h1>
        <SecondComponent langs={this.state.langs} reps={this.state.reps} />
      </main>
    );
  }
}

class SecondComponent extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <ul>
          {this.props.langs.map(l => (
            <button onClick={this.handleClick} id={l}>
              {l}
            </button>
          ))}
          <ReposList reps={this.props.reps} />
        </ul>
      </div>
    );
  }
}

class ReposList extends Component {
  repoToRepoItem = repo => {
    const name = repo.name;
    const owner_avatar_url = repo.owner.avatar_url;
    const owner_html_url = repo.html_url;
    const owner_login = `@${repo.owner.login}`;
    const stargazers_count = `${repo.stargazers_count} stars`;
    return (
      <RepoItem
        name={name}
        owner_avatar_url={owner_avatar_url}
        owner_html_url={owner_html_url}
        owner_login={owner_login}
        stargazers_count={stargazers_count}
      />
    );
  };
  render() {
    if (this.props.reps.length > 0)
      return (
        <ul className="items-container">
          {this.props.reps.map(this.repoToRepoItem)}
        </ul>
      );
    return <p>No results...</p>;
  }
}

const RepoItem = ({
  name,
  owner_avatar_url,
  owner_html_url,
  owner_login,
  stargazers_count
}) => {
  return (
    <li key={name}>
      <img className="avatar" src={owner_avatar_url} alt={name} />
      <h3>
        <a href={owner_html_url}>{name}</a>
      </h3>
      <h4>{owner_login}</h4>
      <p>{stargazers_count}</p>
    </li>
  );
};

export default App;

1 个答案:

答案 0 :(得分:0)

  

我应该在哪个组件中应用过滤道具的功能?

您需要了解在SecondComponent中单击哪个按钮的状态。 例如this.state = {selectedLanguages: []}

然后您需要在下面的代码中传递所选的语言

{this.props.langs.map(l => (
            <button onClick={this.handleClick} id={l}>
              {l}
            </button>
          ))}

通过将事件值传递到this.handleClick来将语言保存到单击状态列表中。

<button onClick={e => this.handleClick(e)} id={l}>

然后,您无需在this.props.langs上进行映射,就需要先对其进行过滤。

类似以下内容(未经测试)。

render() {
    const {langs} = this.props;
    const {selectedLanguages} = this.state;

    // filter only if anything's selected else show all
    const languages = selectedLanguages.length === 0 
        ? langs 
        : langs.filter(lang => selectedLanguages.includes(lang));

    return (
        <div>
        <ul>
            {languages.map(l => (
            <button onClick={this.handleClick} id={l}>
                {l}
            </button>
            ))}
            <ReposList reps={this.props.reps} />
        </ul>
        </div>
    );
}

我可以自己编写整个代码,但其余部分留给您玩耍

我的$ 0.02。与问题无关,但我认为SecondComponent可能需要更明确地重命名,例如FilterableRepoList等。