You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js中如何用输入框过滤Axios请求iTunes的GET结果?

实现iTunes搜索结果的客户端筛选

Hey there! Let's get your React component set up to filter the iTunes API results using an input box. I'll walk you through updating your code step by step, with clear explanations for each part.

完整的组件代码

import React, { Component } from 'react';
import axios from 'axios';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      artists: [], // 存储从iTunes获取的原始数据
      artistSearched: '', // 存储输入框的搜索关键词
      isLoading: false, // 可选:添加加载状态提升用户体验
      error: null // 可选:处理请求错误
    };
    this.handleSearchTermChange = this.handleSearchTermChange.bind(this);
    this.getArtists = this.getArtists.bind(this);
  }

  // 组件挂载时获取初始数据(比如默认搜索"pop"风格艺术家)
  componentDidMount() {
    this.getArtists('pop');
  }

  // 向iTunes API发起请求的方法
  async getArtists(searchTerm) {
    this.setState({ isLoading: true, error: null });
    try {
      const response = await axios.get(`https://itunes.apple.com/search`, {
        params: {
          term: searchTerm,
          media: 'music',
          entity: 'artist'
        }
      });
      // 将返回的结果存入state
      this.setState({ artists: response.data.results, isLoading: false });
    } catch (err) {
      this.setState({ error: '获取数据失败,请稍后重试', isLoading: false });
      console.error('请求错误:', err);
    }
  }

  // 处理输入框内容变化,更新搜索关键词状态
  handleSearchTermChange(e) {
    this.setState({ artistSearched: e.target.value });
  }

  render() {
    const { artists, artistSearched, isLoading, error } = this.state;

    // 根据搜索关键词过滤艺术家列表(不区分大小写)
    const filteredArtists = artists.filter(artist => {
      return artist.artistName.toLowerCase().includes(artistSearched.toLowerCase());
    });

    return (
      <div style={{ maxWidth: '800px', margin: '2rem auto', padding: '0 1rem' }}>
        <h1>iTunes 艺术家搜索</h1>
        
        {/* 受控搜索输入框 */}
        <input
          type="text"
          placeholder="输入艺术家名称筛选..."
          value={artistSearched}
          onChange={this.handleSearchTermChange}
          style={{ width: '100%', padding: '0.5rem', fontSize: '1rem', marginBottom: '1rem' }}
        />

        {/* 加载状态提示 */}
        {isLoading && <p>加载中...</p>}

        {/* 错误提示 */}
        {error && <p style={{ color: 'red' }}>{error}</p>}

        {/* 渲染筛选后的艺术家列表 */}
        <ul style={{ listStyle: 'none', padding: 0 }}>
          {filteredArtists.map(artist => (
            <li key={artist.artistId} style={{ padding: '0.5rem', borderBottom: '1px solid #eee' }}>
              <h3>{artist.artistName}</h3>
              <p>流派: {artist.primaryGenreName}</p>
              {artist.artworkUrl100 && (
                <img 
                  src={artist.artworkUrl100} 
                  alt={artist.artistName} 
                  style={{ width: '50px', height: '50px', borderRadius: '50%' }}
                />
              )}
            </li>
          ))}
        </ul>

        {/* 无匹配结果提示 */}
        {!isLoading && filteredArtists.length === 0 && (
          <p>没有找到匹配的艺术家</p>
        )}
      </div>
    );
  }
}

关键实现点说明

  • 受控输入框: 输入框的value绑定到artistSearched状态,onChange事件触发状态更新,确保输入内容和组件状态完全同步。
  • 客户端筛选逻辑: 使用数组的filter方法,将关键词和艺术家名称统一转为小写,实现不区分大小写的模糊匹配,生成筛选后的列表。
  • 用户体验优化: 增加了加载状态和错误提示,避免用户因等待产生困惑;当无匹配结果时也给出清晰提示。
  • React最佳实践: 列表渲染时使用唯一的artistId作为key属性,避免不必要的重渲染。

可选扩展:实时API搜索

如果想要实现每次输入都发起新的API请求(而非客户端筛选已获取的数据),可以添加防抖(debounce)来避免频繁请求:

// 先引入lodash的debounce(或自行实现简易版)
import debounce from 'lodash/debounce';

// 在constructor中绑定防抖后的请求方法
this.debouncedGetArtists = debounce(this.getArtists, 300);

// 修改输入框变化处理方法
handleSearchTermChange(e) {
  const searchTerm = e.target.value;
  this.setState({ artistSearched: searchTerm });
  // 防抖后发起API请求
  this.debouncedGetArtists(searchTerm);
}

这样既可以实现实时搜索效果,又能避免短时间内多次发起API请求。

内容的提问来源于stack exchange,提问作者Antonio Pavicevac-Ortiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:09:32