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

React:如何根据屏幕宽度调整数组映射渲染的元素数量?

问题分析与解决方案

原代码的核心问题

  1. 初始渲染逻辑错误:直接将numberToMap初始值设为5,没有判断当前屏幕宽度,导致无论窗口大小,初始都显示5个元素。
  2. 事件监听堆积:组件每次渲染都会重复添加change事件监听,窗口调整时会触发大量setNumberToMap调用,直接导致应用冻结。
  3. 媒体查询区间冲突:min-width:1194px和max-width:1195px的区间有重叠(1194px-1195px),会导致两个监听同时触发,逻辑混乱。

简便实现方式

方案一:用useEffect管理监听,初始化时修正显示数量

import { useState, useEffect } from 'react';

// ... 其他组件代码

const [numberToMap, setNumberToMap] = useState(5);

useEffect(() => {
  // 定义统一的媒体查询:屏幕宽度小于1194px
  const mediaQuery = window.matchMedia('(max-width: 1193px)');

  // 定义更新逻辑
  const updateDisplayCount = () => {
    setNumberToMap(mediaQuery.matches ? 4 : 5);
  };

  // 初始化时立即执行一次,确保初始显示正确
  updateDisplayCount();

  // 添加监听
  mediaQuery.addEventListener('change', updateDisplayCount);

  // 组件卸载时清理监听,避免堆积
  return () => {
    mediaQuery.removeEventListener('change', updateDisplayCount);
  };
}, []); // 空依赖数组,仅在组件挂载时执行一次

const mapAnime = () => ( 
  <div className='anime-list-wrapper'>
    {animeData?.data?.slice(0, numberToMap).map((anime) => (
      <AnimeCard anime={anime} key={anime.id} />
    ))}
  </div> 
);

return (
  <div className='container'>
    <h3 className='category-title'>{categoryTitle}</h3>
    {!isFetching && (
      <div className="wrapper">
        {mapAnime()}
      </div>
    )}
  </div>
);

方案二:无需维护state,渲染时直接判断(更简洁)

如果不需要将numberToMap用于其他业务逻辑,可以直接在渲染阶段通过媒体查询结果决定显示数量,省去state的维护成本:

const mapAnime = () => {
  // 直接判断当前屏幕宽度
  const shouldShowFour = window.matchMedia('(max-width: 1193px)').matches;
  const displayCount = shouldShowFour ? 4 : 5;
  
  return (
    <div className='anime-list-wrapper'>
      {animeData?.data?.slice(0, displayCount).map((anime) => (
        <AnimeCard anime={anime} key={anime.id} />
      ))}
    </div>
  );
};

return (
  <div className='container'>
    <h3 className='category-title'>{categoryTitle}</h3>
    {!isFetching && (
      <div className="wrapper">
        {mapAnime()}
      </div>
    )}
  </div>
);

关键优化点

  • 用useEffect包裹事件监听,确保仅添加一次,组件卸载时自动清理,避免监听堆积导致的性能问题。
  • 初始化时主动执行判断逻辑,保证首次渲染的显示数量符合当前屏幕尺寸。
  • 合并媒体查询条件,避免区间重叠引发的逻辑冲突。
  • 方案二减少了state的使用,代码更简洁直观,适合无额外逻辑依赖的场景。

内容的提问来源于stack exchange,提问作者notoriousRorious

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:10:36