首页 > web前端 > js教程 > 正文

React中动态点击分类触发Axios API调用的最佳实践

心靈之曲
发布: 2025-10-18 11:01:00
原创
638人浏览过

React中动态点击分类触发Axios API调用的最佳实践

本文旨在解决在react应用中通过点击不同分类元素来触发动态api调用的常见问题。重点阐述了`

  • `元素`value`属性的误用,并提供了两种正确且语义化的解决方案:利用`

    最直接且语义化的解决方案是使用

    代码示例:

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    const API_BASE_URL = "https://www.themealdb.com/api/json/v1/1/filter.php?c="; // 示例API
    
    function CategoryFilter() {
      const [category, setCategory] = useState("Seafood"); // 初始分类
      const [meals, setMeals] = useState([]);
      const [error, setError] = useState<string | null>(null);
      const [loading, setLoading] = useState(false);
    
      useEffect(() => {
        if (!category) return; // 如果没有分类,则不发起请求
    
        setLoading(true);
        setError(null);
        axios
          .get(`${API_BASE_URL}${category}`)
          .then(function (response) {
            setMeals(response.data.meals || []); // 确保即使没有数据也设置为空数组
          })
          .catch(function (err) {
            console.error("API Error:", err);
            setError("加载数据失败,请稍后再试。");
            setMeals([]);
          })
          .finally(() => {
            setLoading(false);
          });
      }, [category]); // category 改变时重新运行 effect
    
      const onClickHandler = (e: React.MouseEvent<HTMLButtonElement>) => {
        // 使用 e.currentTarget.value 获取 button 的值
        setCategory(e.currentTarget.value);
      };
    
      return (
        <div>
          <h1>菜品分类</h1>
          <ul style={{ listStyle: 'none', padding: 0 }}>
            <li style={{ display: 'inline-block', margin: '0 10px' }}>
              <button value="Seafood" onClick={onClickHandler}>
                海鲜 (Seafood)
              </button>
            </li>
            <li style={{ display: 'inline-block', margin: '0 10px' }}>
              <button value="Vegetarian" onClick={onClickHandler}>
                素食 (Vegetarian)
              </button>
            </li>
            <li style={{ display: 'inline-block', margin: '0 10px' }}>
              <button value="Dessert" onClick={onClickHandler}>
                甜点 (Dessert)
              </button>
            </li>
          </ul>
    
          {loading && <p>加载中...</p>}
          {error && <p style={{ color: 'red' }}>{error}</p>}
          {!loading && !error && meals.length === 0 && <p>未找到相关菜品。</p>}
    
          {!loading && !error && meals.length > 0 && (
            <div>
              <h2>{category} 菜品:</h2>
              <ul>
                {meals.map((meal: any) => (
                  <li key={meal.idMeal}>{meal.strMeal}</li>
                ))}
              </ul>
            </div>
          )}
        </div>
      );
    }
    
    export default CategoryFilter;
    登录后复制

    注意事项:

    VALL-E
    VALL-E

    VALL-E是一种用于文本到语音生成 (TTS) 的语言建模方法

    VALL-E 142
    查看详情 VALL-E
    • 在onClickHandler中,我们使用e.currentTarget.value来获取按钮的值。currentTarget指的是事件监听器所绑定的元素,而target可能是事件实际发生的元素(例如,如果按钮内有文本,target可能是文本节点)。对于按钮,两者通常相同,但currentTarget在处理事件委托时更可靠。
    • 将button嵌套在li中是完全符合语义的,因为li代表列表项,而button是列表项中的一个可交互元素。

    解决方案二:使用 data-* 属性(如果必须使用

  • 如果出于某种设计或结构上的考虑,你坚持要让

  • 元素本身作为可点击项,并且需要传递自定义数据,那么HTML5的data-*属性是理想的选择。data-*属性允许你在标准HTML元素上存储自定义数据,而不会影响其语义或行为。

    代码示例:

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    const API_BASE_URL = "https://www.themealdb.com/api/json/v1/1/filter.php?c="; // 示例API
    
    function CategoryFilterWithDataAttribute() {
      const [category, setCategory] = useState("Seafood"); // 初始分类
      const [meals, setMeals] = useState([]);
      const [error, setError] = useState<string | null>(null);
      const [loading, setLoading] = useState(false);
    
      useEffect(() => {
        if (!category) return;
    
        setLoading(true);
        setError(null);
        axios
          .get(`${API_BASE_URL}${category}`)
          .then(function (response) {
            setMeals(response.data.meals || []);
          })
          .catch(function (err) {
            console.error("API Error:", err);
            setError("加载数据失败,请稍后再试。");
            setMeals([]);
          })
          .finally(() => {
            setLoading(false);
          });
      }, [category]);
    
      const onClickHandler = (e: React.MouseEvent<HTMLLIElement>) => {
        // 使用 e.currentTarget.getAttribute("data-value") 获取自定义数据
        const clickedCategory = e.currentTarget.getAttribute("data-value");
        if (clickedCategory) {
          setCategory(clickedCategory);
        }
      };
    
      return (
        <div>
          <h1>菜品分类 (使用 data-value)</h1>
          <ul style={{ listStyle: 'none', padding: 0 }}>
            <li data-value="Seafood" onClick={onClickHandler} style={{ cursor: 'pointer', display: 'inline-block', margin: '0 10px', padding: '5px 10px', border: '1px solid #ccc' }}>
              海鲜 (Seafood)
            </li>
            <li data-value="Vegetarian" onClick={onClickHandler} style={{ cursor: 'pointer', display: 'inline-block', margin: '0 10px', padding: '5px 10px', border: '1px solid #ccc' }}>
              素食 (Vegetarian)
            </li>
            <li data-value="Dessert" onClick={onClickHandler} style={{ cursor: 'pointer', display: 'inline-block', margin: '0 10px', padding: '5px 10px', border: '1px solid #ccc' }}>
              甜点 (Dessert)
            </li>
          </ul>
    
          {loading && <p>加载中...</p>}
          {error && <p style={{ color: 'red' }}>{error}</p>}
          {!loading && !error && meals.length === 0 && <p>未找到相关菜品。</p>}
    
          {!loading && !error && meals.length > 0 && (
            <div>
              <h2>{category} 菜品:</h2>
              <ul>
                {meals.map((meal: any) => (
                  <li key={meal.idMeal}>{meal.strMeal}</li>
                ))}
              </ul>
            </div>
          )}
        </div>
      );
    }
    
    export default CategoryFilterWithDataAttribute;
    登录后复制

    注意事项:

    • 在HTML中,data-*属性的命名规则是data-前缀后跟自定义名称(如data-value)。
    • 在JavaScript中,你可以通过元素的dataset属性(e.currentTarget.dataset.value)或getAttribute()方法(e.currentTarget.getAttribute("data-value"))来访问这些数据。dataset属性提供了一个更方便的DOMStringMap接口,将data-value转换为dataset.value。
    • 被用作可点击元素时,为了提高用户体验和可访问性,建议为其添加cursor: pointer样式,并考虑添加键盘导航支持。

    总结

    在React应用中实现动态API调用时,选择正确的HTML元素和属性至关重要。

    1. 首选 当你需要一个可点击的交互元素来触发动作并传递值时,
    2. *`data-属性作为备选:** 如果你必须使用非表单元素(如
    3. 等)作为可点击项,并且需要关联自定义数据,那么data-*`属性是最佳方案。它允许你在不违反HTML语义的前提下存储额外信息。
    4. 避免误用
    5. 的value属性:
    6. 记住
    7. 的value属性仅用于指定有序列表中的序数值,不应用于存储自定义字符串数据。
    8. 通过遵循这些最佳实践,你可以构建出更健壮、更易维护且用户体验更好的React应用。

  • 以上就是React中动态点击分类触发Axios API调用的最佳实践的详细内容,更多请关注php中文网其它相关文章!

    最佳 Windows 性能的顶级免费优化软件
    最佳 Windows 性能的顶级免费优化软件

    每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

    下载
    来源:php中文网
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    最新问题
    热门推荐
    开源免费商场系统广告
    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号