反应单击项目以显示详细信息

时间:2018-12-01 12:20:00

标签: javascript reactjs api

我是React的新手,我正在尝试与swapi API进行交互。 我想获取电影列表(电影标题列表),并且当我单击标题以显示json对象中的opens_crawl时。 我设法将电影片头放在一个阵列中。我不知道如何从这里继续。

这是我的代码:

class StarWarsApp extends React.Component {
  render() {
    const title = "Star Wars";
    const subtitle = "Movies";
    return (
      <div>
        <Header title={title} />
        <Movies />
      </div>
    );
  }
}

class Header extends React.Component {
  render() {
    return (
      <div>
        <h1>{this.props.title}</h1>
      </div>
    );
  }
}

class Movies extends React.Component {
  constructor(props) {
    super(props);
    this.handleMovies = this.handleMovies.bind(this);
    this.state = {
      movies: []
    };
    this.handleMovies();
  }

  handleMovies() {
    fetch("https://swapi.co/api/films")
      .then(results => {
        return results.json();
      })
      .then(data => {
        console.log(data);
        let movies = data.results.map(movie => {
          return <div key={movie.episode_id}>{movie.title}</div>;
        });

        this.setState(() => {
          return {
            movies: movies
          };
        });
      });
  }
  render() {
    return (
      <div>
        <h1>Episodes</h1>
        <div>{this.state.movies}</div>
      </div>
    );
  }
}

ReactDOM.render(<StarWarsApp />, document.getElementById("app"));

2 个答案:

答案 0 :(得分:1)

获取数据后,只需保持其状态不变,然后使用组件或JSX中的片段即可。不要从您的handleMovies方法中返回一些JSX,只需在其中执行setState部分即可。另外,我建议使用生命周期方法(如果使用功能组件,则可以使用钩子API)来触发获取。顺便说一句,除非需要状态或生命周期方法,否则不要使用类组件。

之后,可以通过映射电影状态以渲染方法渲染标题。另外,您可以为opening_crawls零件放置一个位置,并使用条件运算符进行渲染。单击此条件即可更改。为此,您需要一个额外的状态属性,并将电影id保留在此处。通过单击,可以将id的值设置为true并显示爬网。

这是一个简单的工作示例。

const StarWarsApp = () => {
  const title = "Star Wars";
  const subtitle = "Movies";
  return (
    <div>
      <Header title={title} />
      <Movies />
    </div>
  );
}

const Header = ({ title }) => (
  <div>
    <h1>{title}</h1>
  </div>
);

class Movies extends React.Component {
  state = {
    movies: [],
    showCrawl: {}
  };

  componentDidMount() {
    this.handleMovies();
  }

  handleMovies = () =>
    fetch("https://swapi.co/api/films")
      .then(results => results.json())
      .then(data => this.setState({ movies: data.results }));

  handleCrawl = e => {
    const { id } = e.target;
    this.setState(current => ({
      showCrawl: { ...current.showCrawl, [id]: !current.showCrawl[id] }
    }));
  };

  render() {
    return (
      <div>
        <h1>Episodes</h1>
        <div>
          {this.state.movies.map(movie => (
            <div
              key={movie.episode_id}
              id={movie.episode_id}
              onClick={this.handleCrawl}
            >
              {movie.title}
              {this.state.showCrawl[movie.episode_id] && (
                <div style={{ border: "1px black solid" }}>
                  {movie.opening_crawl}
                </div>
              )}
            </div>
          ))}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<StarWarsApp />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

我在目标id上使用divevent对象取回它。我不太喜欢这种方法,但是为了清楚起见,我使用了这种方法。您可以对其进行重构并创建另一个组件,然后可以在其中传递epoisde_id并处理setState部分。或者,您可以使用数据属性代替id

答案 1 :(得分:0)

要遍历电影,请将其添加到渲染方法中:

'a

将此方法添加到“电影”组件中,以单击“电影” className将活动类添加到DIV:

render(){
  return (
    <div>
      <h1>Episodes</h1>
      {
        this.state.movies.map((movie, i) => {
          return (
            <div className="movie" onClick={this.handleClick} key={i}>{movie.title}
              <div className="opening">{movie.opening_crawl}</div>
            </div>
          );
        })
      }
    </div>
  );
}

将此CSS包含到您的项目中

handleClick = event => {
  event.currentTarget.classList.toggle('active');
}